Явно обновить DataTemplate из DataTemplateSelector? - PullRequest
17 голосов
/ 18 января 2010

Я настроил ContentControl.DataTemplateSelector на желаемый.
Я хочу, чтобы в соответствии с командой или чем-то еще, вызывал ContentControl для повторного выбора шаблона из селектора с помощью xaml или кода.

Спасибо

Ответы [ 4 ]

19 голосов
/ 16 июня 2011

Опоздал на вечеринку, я знаю. =) * * Тысяча одна

Столкнувшись с этой проблемой, я обнаружил, что проще всего явно установить новый TemplateSelector, например

MyContentControl.ContentTemplateSelector =
     new MyDataTemplateSelector();
10 голосов
/ 19 января 2010

Мне неизвестен какой-либо (не хитрый) способ сделать это: DataTemplateSelector вызывается, когда WPF необходимо выбрать шаблон, и это единственное решение, если речь идет о WPF. (Вы можете запутаться в этом, заставив WPF думать, что контент изменился, например, установив для него значение null, а затем снова вернуться - я думаю, что это сработало бы, но не проверило его - но это довольно уродливо!) хороший способ сделать это, мне тоже было бы интересно узнать!

Однако существует альтернативный способ изменить способ отображения контента, который обновляет в ответ на изменения данных, и это с помощью триггеров. Вы можете использовать DataTriggers в вашей коллекции DataTemplate.Triggers, чтобы показать и скрыть элементы в зависимости от данных содержимого. Чтобы изменить весь дисплей, вы можете, например, установить два рендеринга в сетке и использовать триггеры, чтобы контролировать, какой из них виден. Вы даже можете сделать свой шаблон данных ContentControl и использовать триггер для изменения ContentTemplate. Конечно, это зависит от критериев изменения шаблона, являющихся связываемыми свойствами, что не всегда может иметь место.

Вот краткое обсуждение селекторов и триггеров , хотя и в несколько ином контексте.

8 голосов
/ 04 октября 2012

Полагаю, я еще позже на вечеринке, но для другой идеи, которая может кому-то помочь ...

Вы также можете попробовать использовать ValueConverter в свойстве ContentControl s ContentTemplate вместо DataTemplateSelector.

Просто укажите в вашем DataContext свойство для привязки, например ScreenNumber. Затем в ValueConverter вернуть DataTemplate, который связан с ScreenNumber.

Пример ValueConverter:

public class ValueDataTemplateConverter : IValueConverter
{
    public DataTemplate TemplateA { get; set; }
    public DataTemplate TemplateB { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is ValueType valueType)
            switch (valueType)
            {
                case ValueType.TypeA:
                    return TemplateA;
                case ValueType.TypeB:
                    return TemplateB;
             }

        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Пример ресурса xaml:

<converters:ValueDataTemplateConverter x:Key="ValueDataTemplateConverter">
    <converters:ValueDataTemplateConverter.TemplateA>
        <DataTemplate>
            <TextBox Text="{Binding Value}" />
        </DataTemplate>
    </converters:ValueDataTemplateConverter.TemplateA>
    <converters:ValueDataTemplateConverter.TemplateB>
        <DataTemplate>
            <CheckBox IsChecked="{Binding Value}" />
        </DataTemplate>
    </converters:ValueDataTemplateConverter.TemplateB>
</converters:ValueDataTemplateConverter>
5 голосов
/ 15 июня 2016

Аналогично ответу Дженса, вместо создания нового экземпляра вы можете использовать существующий экземпляр DataTemplateSelector.

var currentSelector = MyContentControl.ContentTemplateSelector;     
MyContentControl.ContentTemplateSelector = null;
MyContentControl.ContentTemplateSelector = currentSelector;
...