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 属性。

因此,您可以在 xaml 中添加 NamedColumn 对象,而不是添加 GridViewColumns。

定义一个派生自 GridViewColumn 的类型:

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

并在您的 xaml 中使用它:

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

现在您应该能够将发件人转换为 NamedColumn 并访问其名称属性。

于 2011-01-06T20:43:03.143 回答
1

你可以使用 column.Header.ToString() 吗?请参阅此处了解为什么无法使用 XAML 中的名称:How to get x:Name value runtime

于 2011-01-06T20:38:45.363 回答
1

感谢您的回答,Robert、Thomas 和 Rune。我喜欢 Runes 的回答,但我发现这里的情况更容易:

我将附加属性的类型从 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 回答
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 回答