Silverlight 4 DataTemplate DataType - PullRequest
       16

Silverlight 4 DataTemplate DataType

6 голосов
/ 04 июля 2010

Silverlight 4 отсутствует, и, похоже, мы снова пропустили функциональность DataTemplate DataType в этом выпуске, что является ключевым моментом для поддержки MVVM IMHO.Для моих приложений WPF, на данный момент, я довольно привык глобально добавлять DataTemplates для моих представлений в мое приложение. Ресурсы с DataTypes для моих соответствующих ViewModels:

то есть.

<DataTemplate DataType="{x:Type viewModels:myViewModel}">
<views:myView/>
</DataTemplate>

Мне нравится этот подход, так как все мои связанные ViewModels автоматически отображают правильное содержимое ... особенно полезно, когда в моем представлении есть какой-то ItemSource, связанный с коллекцией ViewModels ... Это, например, автоматически проверяет каждую вкладку вTabControl, связанный с Collection<SomeViewModel>, отображает представление, связанное с SomeViewModel.

Некоторые вещи, которые я пробовал для SL 3, включают:

  • Создание «DataTemplatePresenterContentControl», который автоматическиприменяет DataTemplate для Контента, когда элемент управления загружен

  • Используя TypeConverter, динамически применяемый при загрузке элемента управления, проходя по визуальному дереву в поисках объектов, связанных с данными

  • Используя стиль, динамически применяемый к контрольной нагрузке, спускаясь вниз по визуальному дереву, выглядяr объекты, связанные с данными

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

Итак, поскольку это все еще невозможно из коробки в Silverlight 4, я был бы признателен, если бы кто-нибудь еще придумал какие-то разумные альтернативы.

Спасибо.

Ответы [ 2 ]

8 голосов
/ 04 марта 2011

Я делаю это в нескольких коммерческих проектах следующим образом:

У меня есть стандартный IValueConverter

public class ViewTemplateChooser : IValueConverter
{
    /// <summary>
    /// Modifies the source data before passing it to the target for display in the UI.
    /// </summary>
    /// <returns>
    /// The value to be passed to the target dependency property.
    /// </returns>
    /// <param name="value">The source data being passed to the target.</param><param name="targetType">The <see cref="T:System.Type"/> of data expected by the target dependency property.</param><param name="parameter">An optional parameter to be used in the converter logic.</param><param name="culture">The culture of the conversion.</param>
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is MyViewModel)
        {
            return new MyView { DataContext = value };
        }

        return value;
    }

    /// <summary>
    /// Modifies the target data before passing it to the source object.  This method is called only in <see cref="F:System.Windows.Data.BindingMode.TwoWay"/> bindings.
    /// </summary>
    /// <returns>
    /// The value to be passed to the source object.
    /// </returns>
    /// <param name="value">The target data being passed to the source.</param><param name="targetType">The <see cref="T:System.Type"/> of data expected by the source object.</param><param name="parameter">An optional parameter to be used in the converter logic.</param><param name="culture">The culture of the conversion.</param>
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Для преобразователя потребуется регистрация пространства имен

xmlns:Converters="clr-namespace:YourProject.Converters" 

Затем вы ссылаетесь на конвертер в разделе ресурсов:

<UserControl.Resources>
    <Converters:ViewTemplateChooser x:Key="TemplateChooser" />
</UserControl.Resources>

и, наконец, я использую конвертер для преобразования ViewModel в View с Datacontext для представления, установленного в ViewModel

<ContentControl Content="{Binding Workspace, Converter={StaticResource TemplateChooser}}" Margin="5,35,5,5" Grid.Column="1" />

Конвертер можно модифицировать для реализации стратегий навигации, я постарался максимально упростить пример.

Надеюсь, это поможет, вам не нужно идти на крайние меры - или на стороннихбиблиотеки - чтобы получить то, что вы ищете.

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

В WPF и Silverlight я использую Prism для этого. Я считаю, что гораздо более универсальным является переключение представлений на основе типов. Требуется немного, чтобы привязать его, но как только он появляется, возможности безграничны.

Редактировать

Я делаю это, привязывая RegionName к свойству в моей ViewModel (может быть GetType (). Name, если хотите). Затем я регистрирую типы для имен, и это просто работает.

В случае чего-то вроде ListBox я настроил шаблон данных так:

<ContentControl Regions:RegionManager.RegionName="{Binding SomeName}" />

Если вы не хотите, чтобы SomeName находился на объекте, к которому вы привязываете, рассмотрите ValueConverter, который возвращает имя типа:

<ContentControl Regions:RegionManager.RegionName="{Binding SomeName, Converter={StaticResource ObjectToTypeConverter}}" />

Это помогает?

...