0

GridView があり、セッション間で列幅をシリアル化したい。これを達成する方法についての私の考えは、列の幅が変更されるたびに、添付されたイベント ハンドラーが呼び出されて新しい幅が格納されるように、GridViewColumns にビヘイビアを添付することです。これはすでにうまく機能しています。

唯一残っている問題:

どのGridViewColumn がイベントを送信したかをイベント ハンドラーで知るにはどうすればよいですか? 幅を保存し、後で復元するときに正しい列に幅を設定できるようにするためには、明らかにそれを知る必要があります。理想的には、XAML で指定された名前を列識別子として使用したいと考えています。

これが私のコードです。XAML :

<GridView>
  <GridViewColumn x:Name="GridColumn0"
    HeaderTemplate="{StaticResource GridViewHeaderTemplate}" HeaderContainerStyle="{StaticResource GridViewHeaderStyle}" 
    Header="{x:Static strings:Strings.MainWindow_AppLog_Header_Severity}"
    behaviors:GridViewBehaviors.PersistColumnWidth="True">

C# (下にスクロールしてください - 一番下の質問):

// Register the property used in XAML
public static readonly DependencyProperty PersistColumnWidthProperty =
     DependencyProperty.RegisterAttached("PersistColumnWidth", typeof(bool), typeof(GridViewBehaviors),
     new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnPersistColumnWidthChanged)));

// Provide read access to the value
public static bool GetPersistColumnWidth(DependencyObject d)
{
    return (bool)d.GetValue(PersistColumnWidthProperty);
}

// Provide write access to the value (set from XAML)
public static void SetPersistColumnWidth(DependencyObject d, bool value)
{
    d.SetValue(PersistColumnWidthProperty, value);
}

// This gets called once when the XAML is compiled to BAML
// Set the event handler
private static void OnPersistColumnWidthChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
    GridViewColumn column = sender as GridViewColumn;
    if (column == null)
        return;

    // Couple the UI event with a delegate
    if ((bool)args.NewValue)
        ((INotifyPropertyChanged)column).PropertyChanged += new PropertyChangedEventHandler(PersistWidth);
    else
        ((INotifyPropertyChanged)column).PropertyChanged -= new PropertyChangedEventHandler(PersistWidth);
}

// Deal with the events
static void PersistWidth(object sender, PropertyChangedEventArgs e)
{
    GridViewColumn column = sender as GridViewColumn;
    if (column == null)
        return;

    // We are only interested in changes of the "ActualWidth" property
    if (e.PropertyName != "ActualWidth")
        return;

    // Ignore NaNs
    if (column.ActualWidth == double.NaN)
        return;

    // Persist the width here
    // PROBLEM:
    // How to get a unique identifier for column, ideally its name set in XAML?
}
4

4 に答える 4

3

x:Name にアクセスできるとは思いませんが、設定できる Name プロパティを持つ独自の列タイプを定義できるはずです。

したがって、GridViewColumns を追加する代わりに、xaml に NamedColumn オブジェクトを追加します。

GridViewColumn から派生する型を定義します。

public class NamedColumn : GridViewColumn
{
   public string ColumnName {get; set;}
}

そしてあなたのxamlでそれを使用してください:

<GridView>
  <NamedColumn ColumnName="GridColumn0" .... blablalba more stuff here />
  ...

これで、送信者を NamedColumn にキャストし、その name プロパティにアクセスできるはずです。

于 2011-01-06T20:43:03.143 に答える
1

回答ありがとうございます、ロバート、トーマス、ルーン。私はルーンの答えが好きですが、ここで私の状況にもっと簡単なものを見つけました:

添付プロパティのタイプをboolからstringに変更し、列の名前をそこに格納するだけです。関連する変更は以下のとおりです。

XAML:

<GridViewColumn 
  behaviors:GridViewBehaviors.PersistColumnWidth="MainWindow_AppLog_Column0">

C#:

public static readonly DependencyProperty PersistColumnWidthProperty = 
  DependencyProperty.RegisterAttached("PersistColumnWidth", typeof(string),
  typeof(GridViewBehaviors), new FrameworkPropertyMetadata(string.Empty, 
  new PropertyChangedCallback(OnPersistColumnWidthChanged)));

static void PersistWidth(object sender, PropertyChangedEventArgs e)
{
  // This now yields "MainWindow_AppLog_Column0"
  string columnID = GetPersistColumnWidth(column);
于 2011-01-06T21:14:44.267 に答える
1

column.Header.ToString() を使用できますか? XAML からの名前が使用できない理由については、こちらを参照してください: x:Name 値のランタイムを取得する方法

于 2011-01-06T20:38:45.363 に答える
0

うまくいくかどうかはわかりませんが、次のようなことを試すことができます。

INameScope nameScope = NameScope.GetNameScope(column);
string name = nameScope
               .Where(kvp => kvp.Value == column)
               .Select(kvp => kvp.Key.ToString())
               .FirstOrDefault();
于 2011-01-06T20:45:52.807 に答える