Вопрос

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

Спасибо

Это было полезно?

Решение

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

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

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

Другие советы

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

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

MyContentControl.ContentTemplateSelector =
     new MyDataTemplateSelector();

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

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

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

Пример преобразования значений:

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>

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

var currentSelector = MyContentControl.ContentTemplateSelector;     
MyContentControl.ContentTemplateSelector = null;
MyContentControl.ContentTemplateSelector = currentSelector;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top