WPF: Как получить имя или другой уникальный идентификатор вызывающего объекта в обработчике событий для сериализации? - PullRequest
0 голосов
/ 06 января 2011

У меня есть 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 ]

3 голосов
/ 06 января 2011

Я не думаю, что вы сможете получить доступ к x: Name, но вы должны быть в состоянии определить свой собственный тип столбца, который имеет свойство Name, которое вы можете установить.

Таким образом, вместо добавления GridViewColumns вы добавляете объекты NamedColumn в свой xaml.

Определите тип, производный от GridViewColumn:

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

И используйте это в своем xaml:

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

Теперь вы должны быть в состоянии привести отправителя к NamedColumn и получить доступ к его свойству name.

1 голос
/ 07 января 2011

Спасибо за ваши ответы, Роберт, Томас и Руна.Мне нравится ответ Руны, но я нашел что-то еще более простое для моей ситуации здесь :

Я изменил тип присоединенного свойства с 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);
1 голос
/ 06 января 2011

вы можете использовать column.Header.ToString ()? см. здесь, почему имя из XAML невозможно: Как получить x: Имя значения время выполнения

0 голосов
/ 06 января 2011

Я не уверен, что это сработает, но вы можете попробовать что-то вроде этого:

INameScope nameScope = NameScope.GetNameScope(column);
string name = nameScope
               .Where(kvp => kvp.Value == column)
               .Select(kvp => kvp.Key.ToString())
               .FirstOrDefault();
...