Явно обновить DataTemplate из DataTemplateSelector?
-
21-09-2019 - |
Вопрос
Я настроил ContentControl.DataTemplateSelector на мой желаемый.
Я хочу, чтобы в соответствии с командой или чем-то еще, вызовите ContentControl, чтобы повторно выбрать шаблон из селектора либо с помощью xaml, либо с помощью кода.
Спасибо
Решение
Я не знаю ни одного (нескладного) способа сделать это:DataTemplateSelector вызывается, когда WPF необходимо выбрать шаблон, и это одноразовое решение, насколько это касается WPF.(Вы можете отключить это, заставив WPF думать, что содержимое изменилось, напримерустановив для содержимого значение null, а затем обратно - я думаю, что это сработало бы, но я не тестировал это - но это довольно некрасиво!) Если есть хороший способ сделать это, мне тоже было бы интересно узнать!
Однако существует альтернативный способ изменить способ отображения содержимого, который делает обновляйте в ответ на изменения данных, и это происходит с помощью триггеров.Вы можете использовать DataTriggers в вашем DataTemplate.Triggers
коллекция для отображения и скрытия элементов в зависимости от данных содержимого.Чтобы изменить весь дисплей целиком, вы могли бы, напримернастройте два рендеринга в сетке и используйте триггеры для управления тем, какой из них виден.Вы даже могли бы сделать свой шаблон данных ContentControl и использовать триггер для изменения ContentTemplate.Конечно, это зависит от критериев изменения свойств шаблона, являющихся привязываемыми, что может быть не всегда так.
Вот краткое обсуждение селекторов противтриггеры, хотя и в несколько ином контексте.
Другие советы
Опаздываю на вечеринку, я знаю.=)
Столкнувшись с этой проблемой, я обнаружил, что проще всего явно установить новый TemplateSelector, например
MyContentControl.ContentTemplateSelector =
new MyDataTemplateSelector();
Я предполагаю, что я еще позже приду на вечеринку, но из-за другой идеи, которая может кому-то помочь...
Вы также могли бы попробовать использовать ValueConverter
на ContentControl
s 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;