Почему этот объект Silverlight 4 DependencyObject DependencyProperty не привязывает данные? - PullRequest
2 голосов
/ 20 июля 2010

Понятия не имею, почему привязка данных не происходит для определенных объектов в моем приложении Silverlight 4. Вот как выглядит мой XAML:

<sdk:DataGrid>
  <u:Command.ShortcutKeys>
    <u:ShortcutKeyCollection>
      <u:ShortcutKey Key="Delete" Command="{Binding Path=MyViewModelProperty}"/>
    </u:ShortcutKeyCollection>
  </u:Command.ShortcutKeys>
</sdk:DataGrid>

Контекст данных установлен очень хорошо, так как другие привязки данных, которые я установил в сетке, работают очень хорошо. Command.ShortcutKeys - это прикрепленный DependencyProperty, который объявлен следующим образом:

public static readonly DependencyProperty ShortcutKeysProperty = DependencyProperty.RegisterAttached(
    "ShortcutKeys", typeof(ShortcutKeyCollection),
    typeof(Command), new PropertyMetadata(onShortcutKeysChanged));

private static void onShortcutKeysChanged(
    DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
    var shortcuts = args.NewValue as ShortcutKeyCollection;
    if (obj is UIElement && shortcuts != null)
    {
        var element = obj as UIElement;
        shortcuts.ForEach(
            sk => element.KeyUp += (s, e) => sk.Command.Execute(null));
    }
}

public static ShortcutKeyCollection GetShortcutKeys(
    DependencyObject obj)
{
    return (ShortcutKeyCollection)obj.GetValue(ShortcutKeysProperty);
}

public static void SetShortcutKeys(
    DependencyObject obj, ShortcutKeyCollection keys)
{
    obj.SetValue(ShortcutKeysProperty, keys);
}

Я знаю, что это присоединенное свойство работает нормально, так как обработчики событий запускаются. Однако свойство Command объектов ShortcutKey не привязывается к данным. Вот определение ShortcutKey:

public class ShortcutKey : DependencyObject
{
    public static readonly DependencyProperty KeyProperty = DependencyProperty.Register(
        "Key", typeof(Key), typeof(ShortcutKey), null);
    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
        "Command", typeof(ICommand), typeof(ShortcutKey), null);

    public Key Key
    {
        get { return (Key)GetValue(KeyProperty); }
        set { SetValue(KeyProperty, value); }
    }

    public ICommand Command
    {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }
}

public class ShortcutKeyCollection : ObservableCollection<ShortcutKey> { }

Свойство, к которому привязывается, имеет значение, установленное в конструкторе моей модели представления, и его тип равен ICommand. Так почему же мое свойство Command не связывает данные? Кроме того, вы нашли эффективный способ отладки проблем с привязкой данных в Silverlight?

Edit:

По крайней мере, одной ошибкой было то, что ShortcutKey является производным от DependencyObject вместо FrameworkElement, который, по-видимому, является единственным корневым классом, к которому может применяться привязка. Однако даже после этого изменения привязка продолжала работать неправильно.

Ответы [ 2 ]

1 голос
/ 20 июля 2010

Необходимо указать источник привязки, поскольку DataContext не наследуется членами ObservableCollection.

edit:

Попробуйте установить ShortcutKey.DataContext в onShortcutKeysChanged:

private static void onShortcutKeysChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
  var shortcuts = args.NewValue as ShortcutKeyCollection;
  if (obj is FrameworkElement && shortcuts != null)
  {
    var element = obj as FrameworkElement;
    ForEach(ShortcutKey sk in shortcuts) 
    {
      sk.DataContext = element.DataContext;
      element.KeyUp += (s, e) => sk.Command.Execute(null));
    }
  }
}
0 голосов
/ 20 июля 2010

Похоже, если объект не вставлен в визуальное дерево, не происходит DataContext наследование, и, следовательно, привязка данных не работает.Я не смог найти способ передать контекст данных контейнера объектам ShortcutKey, поэтому в качестве обходного пути я установил привязку в коде позади.

Надеюсь, у кого-то другой есть другойответ, который покажет мне, как мне не придется прибегать к настройке привязки данных в коде.

...