Как сделать привязку поддержки UIElement? - PullRequest
3 голосов
/ 20 мая 2011

DependencyProperties на UIElement s не поддерживает привязку данных (вы получаете что-то вроде:

"Не могу найти управляющих FrameworkElement .. ")

. Если вы попытаетесь, вы получите ошибку, потому что WPF не может разрешить DataContext. Насколько я знаю, вы получаете поддержку связывания, если вы наследуете FrameworkElement или Freezable, но в этом случае я не могу просто изменить базовый класс. Есть ли способ получить UIElement для поддержки привязки данных?

Я пытался добавить свойство DataContext в класс UIElement следующим образом:

  FrameworkElement.DataContextProperty.AddOwner(typeof(Bitmap), new 
    FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits));

Я также попытался выполнить привязку, указав «ElementName» в выражении привязки, но я все еще не могу разрешить родительский DataContext (я думал, что привязка явно с помощью ElementName просто избавит от необходимости разрешать DataContext).

Это связывание. Данный класс называется «Растровое изображение».

<Utils:Bitmap Source="{Binding Path=Icon}" />
<TextBlock Grid.Row="1" Grid.ColumnSpan="3" MaxWidth="90" Text="{Binding Path=Name}" TextWrapping="Wrap" TextAlignment="Center"/>

Привязка текстового блока работает как положено, первая привязка - нет. Связанная модель представления имеет оба свойства (я ранее связывался с классом Image, и он работал).

Класс растрового изображения можно найти в этом блоге: http://blogs.msdn.com/b/dwayneneed/archive/2007/10/05/blurry-bitmaps.aspx

При некоторой расширенной диагностике привязки я получаю следующий вывод:

System.Windows.Data Warning: 65 : BindingExpression (hash=14926099): Framework mentor not found
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Icon; DataItem=null; target element is 'Bitmap' (HashCode=117163); target property is 'Source' (type 'BitmapSource')
System.Windows.Data Warning: 63 : BindingExpression (hash=6195855): Resolving source  (last chance)
System.Windows.Data Warning: 65 : BindingExpression (hash=6195855): Framework mentor not found
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Icon; DataItem=null; target element is 'Bitmap' (HashCode=55762700); target property is 'Source' (type 'BitmapSource')
System.Windows.Data Warning: 63 : BindingExpression (hash=48657561): Resolving source  (last chance)
System.Windows.Data Warning: 65 : BindingExpression (hash=48657561): Framework mentor not found
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Icon; DataItem=null; target element is 'Bitmap' (HashCode=35264868); target property is 'Source' (type 'BitmapSource')

Ответы [ 3 ]

7 голосов
/ 20 мая 2011

Вы должны наследовать FrameworkElement, чтобы использовать привязку данных. Если вы не можете изменить базовый класс, единственный вариант, который у вас есть, как H.B. сказал, создайте адаптер, который будет производным от FrameworkElement и делегировать все функциональные возможности экземпляру существующего класса, производного от UIElement.

См. http://msdn.microsoft.com/en-us/library/ms743618.aspx для получения дополнительной информации о том, что предоставляют базовые классы инфраструктуры (например, UIElement и FrameworkElement).

Обновление:

Несмотря на то, что в MSDN (ссылка выше) говорится, что поддержка привязки данных введена на уровне FrameworkElement, можно установить привязку для любого DependencyObject. Единственное, что в этом случае вы не можете использовать DataContext в качестве неявного источника для привязки, и вы не можете использовать ElementName для ссылки на источник.

Что вы можете сделать, это установить привязку программно и указать источник явно:

BindingOperations.SetBinding(MyBitmap, Bitmap.IconProperty, new Binding() { Source = this.DataContext /* Or any other source */, Path = new PropertyPath("Icon")});

ИЛИ вы можете использовать небольшую хитрость и использовать RelativeSource для ссылки на элемент в визуальном дереве (в данном случае любой родительский элемент FrameworkElement):

<Utils:Bitmap Source="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type FrameworkElement}}, Path=DataContext.Icon}" />
4 голосов
/ 16 декабря 2011

Вы можете использовать {Binding Source={x:Reference elementName}} вместо {Binding ElementName=elementName}.

1 голос
/ 20 мая 2011

Как уже отмечалось, вы можете связываться с любым объектом, который наследуется от DependencyObject, если вы хотите DataContext, я бы посоветовал вам просто сделать наследование класса от FrameworkElement.Даже такие формы, как Rectangle, делают это, если у вас есть какой-то элемент управления изображением, имеет смысл выбрать более высокий уровень в качестве базового класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...