Реализация пользовательских свойств «пути» внутри пользовательского элемента управления - PullRequest
0 голосов
/ 16 февраля 2012

Как вы могли заметить, элементы управления ComboBox, ListBox и такого рода "селекторы" используют некоторые свойства с суффиксом "путь", который позволяет привязывать объекты с разными именами свойств к его шаблону данных без изменения самого шаблона.

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

<my:ACustomControl HeadingPath="SomePropertyOfModelA" ContentPath="OtherPropertyFromModelA" ItemsSource="{Binding ModelA}"... />

... и ничего не меняя в элементе управленияили его шаблон данных может это сделать

<my:ACustomControl HeadingPath="DifferentPropertyFromModelB" ContentPath="NewPropertyFromB" ItemsSource="{Binding ModelB}" ... />

Мне не очень нравится подход динамического построения таблицы данных с использованием конкатенации строк ...

Есть идеи?

РЕДАКТИРОВАТЬ:

ОК,

Это работает сейчас, но на моем подходе есть темное пятно.Поскольку я использую ValueConverters для получения фактического значения свойства, и этот преобразователь значений создается в Xaml как статический ресурс, я обнаружил, что при отображении usercontrol присутствует некоторый порядок приоритетов, поскольку ItemsControl получает данные элементов перед ValueConvertersполучает название собственности.В результате ничего не конвертируется.

Мой обходной путь заключался в том, чтобы принудительно установить значение PathProperty ValueConverter из кода сразу после установки значения HeadingPath.Вот почему статический ресурс имеет x: Name и x: Key.

Вот что я сделал до сих пор.(Пожалуйста, рассмотрите это как песочницу, извините за то, что не позаботились о соглашениях об именах и т. Д.)

1.- Создайте пользовательский элемент управления с ItemsControl внутри, например:

<ItemsControl x:Name="InternalItemsControl" ItemsSource="{Binding Items, Mode=TwoWay}">

Где Items - это свойство зависимости в коде, стоящем за

2.- Установите CodeBehind в качестве DataContext для usercontrol LayoutRoot Grid в конструкторе класса

Public Sub New()
    InitializeComponent()
    LayoutRoot.DataContext = Me 
End Sub

3.- Определите свойство зависимости с именем Itemsв коде Позади

4.- Определите свойство зависимости с именем HeadingPath типа string для хранения имени свойства бизнес-объекта

5.- Создайте реализацию IVaueConverter, которая также наследуется от DependencyObject и реализует INotifyPropertyChanged следующим образом

Imports System.Windows.Data
Imports System.ComponentModel

Public Class PathPropertiesValueConverter
    Inherits DependencyObject
    Implements IValueConverter
    Implements INotifyPropertyChanged
    ...

6.- Определите свойство зависимости внутри реализации IValueConverter с именем PathProperty типа string для хранения имени свойства, значение которого будет использоваться в качестве возвращаемого значения при преобразовании данных.

7.- При преобразовании метода ...:

    Public Function Convert(value As Object, targetType As System.Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
        If value IsNot Nothing AndAlso Not String.IsNullOrEmpty(PathProperty) Then
            Return value.GetType.GetProperty(PathProperty).GetValue(value, Nothing)
        Else
            Return Nothing
        End If
    End Function

8.- Создание IValueConvошибочная реализация в качестве статического ресурса в usercontrol

<local:PathPropertiesValueConverter x:Key="PathConverter" x:Name="HeadingPathConverter" 
    PathProperty="{Binding ElementName=LayoutRoot, Path=DataContext.HeadingPath, Mode=TwoWay}" />

9.- После этого вы можете использовать имя свойства как строку в свойстве HeadingPath для привязки ChildItems к ItemsControl из любого silverlight Page:

    <StackPanel Orientation="Vertical" >
        <local:MyCustomControl HeadingPath="PropiedadA" Items="{Binding Listado, Mode=TwoWay}" />
        <local:MyCustomControl HeadingPath="PropiedadB" Items="{Binding Listado2, Mode=TwoWay}" />
    </StackPanel>

10. Быть Listado и Listado 2 ObservableCollections, загруженными данными и всем связующим материалом на этом уровне набора ... это результат:

http://dl.dropbox.com/u/6450273/PathProperties.JPG

1 Ответ

0 голосов
/ 16 февраля 2012

Я думаю, что вашим лучшим вариантом будет создание DataTemplate самостоятельно.За кулисами DisplayMemberPath в основном создает шаблон данных с привязкой TextBlock к свойству.SelectedValuePath - это просто DependencyProperty с PropertyChangedCallback, который устанавливает путь привязки выбранного значения.В конечном счете, любое пользовательское свойство, которое вы создаете, просто будет ярлыком для некоторых функций, которые вы определили в другом месте.

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