2010-09-20 3 views
1

Я работаю над приложением, которое использует богато отформатированный ListBox. Одна из вещей, которые мне нужны, - связать несколько фрагментов информации с кнопкой, которая находится в DataTemplate ListBox.WPF - DataTemplate - Использование привязки элементов в прикрепленном свойстве

Это чрезмерное упрощение моего фактического кода, который я сделал, чтобы помочь вам разобраться в проблеме.

Вот кусок XAML внутри DataTemplate, который работает:

<Button Command="local:MediaCommands.StreamVideo" 
    CommandParameter="{Binding Path=Folder}" /> 

При нажатии на кнопку, он посылает Folder свойство элемента данных, что этот список основан вокруг (член ItemsSource, что отображается текущий элемент списка). Однако мне нужна еще одна часть данных, свойство Filename текущего элемента. Для этого я создал новый класс, FileInfo, который содержит свойства зависимостей для Folder и Filename. Затем я заменил код XAML раньше с:

<Button Command="local:MediaCommands.StreamVideo"> 
    <Button.CommandParameter> 
     <data:FileInfo Folder="{Binding Path=Folder}" 
      Filename="{Binding Path=Filename}" /> 
    </Button.CommandParameter> 
</Button> 

Однако, единственное, что мой код посылает меня это пустой FileInfo объект. Обратите внимание, что если я изменил XAML выше, чтобы включить литеральные значения для Folder и Filename, код работает отлично, в том смысле, что он правильно создает объект FileInfo и назначает правильные свойства.

Для справки, мой FileInfo класс выглядит немного как это:

class FileInfo : DependencyObject { 
    public static readonly DependencyProperty FolderProperty; 
    public static readonly DependencyProperty FilenameProperty; 
    static FileInfo() { 
     FolderProperty = DependencyProperty.Register("Folder", 
      typeof(string), typeof(FileInfo)); 
     FilenameProperty = DependencyProperty.Register("Filename", 
      typeof(string), typeof(FileInfo)); 
    } 
    public string Folder { 
     get { return (string) GetValue(FolderProperty); } 
     set { SetValue(FolderProperty, value); } 
    } 
    public string Filename { 
     get { return (string) GetValue(FilenameProperty); } 
     set { SetValue(FilenameProperty, value); } 
    } 
} 

Игнорируя тот факт, что в этом случае, я мог бы просто передать ссылку на сам объект данных (в моем реальном приложении, я нужно извлечь данные из пары вложенных ListBox, но проблема такая же), может ли кто-нибудь увидеть, что здесь происходит? Не были ли мои свойства зависимостей не объявлены должным образом? Нужно ли мне делать что-то причудливое с привязками?

+0

Очень озадачивает. Одна вещь, которая помогает мне разобраться в проблемах с привязкой, заключается в том, чтобы включить брошенный вариант в Debug -> Exceptions -> Managed Debugging Assistants -> BindingFailure. Может быть, отладчик скажет вам что-то полезное, если вы это сделаете. – Jacob

+0

Я включил эту функцию, но ничего не сообщал. Это должно быть что-то еще. – Ethan

ответ

3

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

+0

Я попытался сделать 'FileInfo' наследовать от' FrameworkElement' вместо 'DependencyObject', но это не устранило проблему. Я неправильно понял ваше решение? – Ethan

+2

Джон упомянул также, что объект должен быть частью визуального дерева, чтобы сделать наследование DataContext. В вашем случае FileInfo нет. Таким образом, он не получает DataContext. В любом случае, одно из возможных решений для того, что у вас есть, это иметь IValueConverter, который возвращает экземпляр FileInfo, заданный вашим классом данных. При этом ваш CommandParameter будет объявлен как

+0

Проблема, которую я вижу с этим (и это может быть не проблема), заключается в том, что мои данные поступают не только из моего класса данных. Скорее, мне нужно поле из моего класса данных и два поля из других элементов ('ListBox') в шаблоне данных.Строго говоря, я мог просто не возвращать параметр и программировать обратный вызов кнопки, чтобы он проходил через дерево элементов, но это потребовало бы большой работы и было бы ужасно неэлегантным. Я чувствую, что должно быть лучшее решение. – Ethan

Смежные вопросы