我有ContentControl,我的DataTemplateSelector也支持null值。
<ContentControl Content="{x:Bind CurrentItem, Mode=OneWay}">
<ContentControl.DataTemplateSelector>
<my:DataTemplateSelector>
<my:DataTemplateSelector.NullTemplate>
<DataTemplate>
<Border Background="Red" />
</DataTemplate>
</my:DataTemplateSelector.NullTemplate>
<my:DataTemplateSelector.CustomTemplate1>
<DataTemplate>
<Border Background="Green" />
</DataTemplate>
</my:DataTemplateSelector.CustomTemplate1>
<my:DataTemplateSelector.CustomTemplate2>
<DataTemplate>
<Border Background="Blue" />
</DataTemplate>
</my:DataTemplateSelector.CustomTemplate2>
</my:DataTemplateSelector>
</ContentControl.DataTemplateSelector>
</ContentControl>
问题是当CurrentItem变为null时,它不会调用DataTemplateSelector中的SelectTemplateCore方法。实际上只有在第一次加载控件且CurrentItem为空时才选择NullTemplate。
我可以用虚拟对象替换null值,但是处理这个问题要困难得多。 我找到了this解决方案,但它仅适用于WPF(UWP没有Style.Triggers)
答案 0 :(得分:0)
我不确定你的ContentControl.DataTemplateSelector
是什么,我想这是UWP中的ContentControl.ContentTemplateSelector。
问题是当CurrentItem更改为null时,它不会调用DataTemplateSelector中的SelectTemplateCore方法。实际上只有在第一次加载控件且CurrentItem为空时才选择NullTemplate。
是的,你是对的。如果您稍后将CurrentItem
设置为空,则TemplateSelector
将不会再次遇到DataTemplateSelector
。您需要的是为CurrentItem
创建一个可为空的属性。例如:
<Page.Resources>
<DataTemplate x:Key="NullTemplate">
<Border Background="Red" Height="300" Width="300">
<TextBlock Text="{Binding TemplateName}" />
</Border>
</DataTemplate>
<DataTemplate x:Key="CustomTemplate1">
<Border Background="Green" Height="300" Width="300">
<TextBlock Text="{Binding TemplateName}" />
</Border>
</DataTemplate>
<DataTemplate x:Key="CustomTemplate2">
<Border Background="Blue" Height="300" Width="300">
<TextBlock Text="{Binding TemplateName}" />
</Border>
</DataTemplate>
<local:MyDataTemplateSelector x:Key="MyDataTemplateSelector"
NullTemplate="{StaticResource NullTemplate}"
CustomTemplate1="{StaticResource CustomTemplate1}"
CustomTemplate2="{StaticResource CustomTemplate2}" />
</Page.Resources>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ComboBox x:Name="combo" SelectionChanged="combo_SelectionChanged">
<ComboBoxItem Content="NullTemplate" />
<ComboBoxItem Content="CustomTemplate1" />
<ComboBoxItem Content="CustomTemplate2" />
<ComboBoxItem Content="SetCurrentItemToNull" />
<ComboBoxItem Content="SetCurrentItemPropertyToNull" />
</ComboBox>
<ContentControl Content="{x:Bind CurrentItem, Mode=OneWay}" Margin="0,10"
ContentTemplateSelector="{StaticResource MyDataTemplateSelector}" />
</StackPanel>
代码背后的代码:
private ContentControlDataModel _CurrentItem;
public ContentControlDataModel CurrentItem
{
get { return _CurrentItem; }
set
{
if (value != _CurrentItem)
{
_CurrentItem = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName]string propertyName = "")
{
if (this.PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private void combo_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var item = combo.SelectedItem as ComboBoxItem;
switch (item.Content.ToString())
{
case "NullTemplate":
CurrentItem = new ContentControlDataModel { Template = null, TemplateName = "NullTemplate" };
break;
case "CustomTemplate1":
CurrentItem = new ContentControlDataModel { Template = true, TemplateName = "CustomTemplate1" };
break;
case "CustomTemplate2":
CurrentItem = new ContentControlDataModel { Template = false, TemplateName = "CustomTemplate2" };
break;
case "SetCurrentItemToNull":
CurrentItem = null;
break;
case "SetCurrentItemPropertyToNull":
CurrentItem = new ContentControlDataModel { Template = null, TemplateName = null };
break;
}
}
ContentControlDataModel
是这样的:
public class ContentControlDataModel
{
public bool? Template { get; set; } //nullable property
public string TemplateName { get; set; }
}
和MyDataTemplateSelector
:
public class MyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate NullTemplate { get; set; }
public DataTemplate CustomTemplate1 { get; set; }
public DataTemplate CustomTemplate2 { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
var model = item as ContentControlDataModel;
if (model == null || model.Template == null)
return this.NullTemplate;
else
{
return (bool)model.Template ? this.CustomTemplate1 : this.CustomTemplate2;
}
}
}
渲染图片:
您可以选择ComboBox
的不同项目来检查差异。