C# 将ContentTemplateSelector绑定到不同的对象然后绑定到内容(ContentPresenter)
查看我的代码,我意识到我的许多基于C# 将ContentTemplateSelector绑定到不同的对象然后绑定到内容(ContentPresenter),c#,wpf,data-binding,C#,Wpf,Data Binding,查看我的代码,我意识到我的许多基于DataTemplateSelector的类做了几乎相同的事情,例如检查绑定对象的bool属性。我真的不想让一堆对象做的差不多一样,但我对我的想法并不完全满意 我最喜欢的想法是将我需要的对象绑定到模板,并让我的DataTemplateSelector具有一个属性,可以设置为应该用于选择模板的布尔属性的名称(在我的xaml中实例化选择器时提供名称)。 在选择器中,我将使用反射来访问属性 第二个想法是只绑定我的布尔属性,然后在我的模板中使用到祖先DataContex
DataTemplateSelector
的类做了几乎相同的事情,例如检查绑定对象的bool
属性。我真的不想让一堆对象做的差不多一样,但我对我的想法并不完全满意
我最喜欢的想法是将我需要的对象绑定到模板,并让我的DataTemplateSelector
具有一个属性,可以设置为应该用于选择模板的布尔属性的名称(在我的xaml中实例化选择器时提供名称)。
在选择器中,我将使用反射来访问属性
第二个想法是只绑定我的布尔属性,然后在我的模板中使用到祖先DataContext
的相对绑定,并从那里开始工作。我不喜欢这样,因为这看起来非常违反直觉,维护起来很糟糕
我可以为此实现一个接口(这样布尔属性将始终具有相同的名称),但这意味着我将在模型中有一些仅用于视图的代码。或者在ViewModel
中实现接口,并且不能让多个DataTemplateSelector
在同一个控件中执行此操作(不为此目的拆分为类)
只需按名称绑定。非常简单的解决方案,但如果您想在多个控件中重用模板,则该解决方案实际上不起作用。如果我需要模板的地方有一个UserControl
,我会选择该解决方案。只需将其作为此UserControl
的资源,并拥有一个简单且可维护的解决方案。只要您我不想在多个控件中使用模板,这绝对没有问题
还有其他我忽略的想法吗?对上面列出的事情有什么评论吗
澄清的示例代码
注意:由于我不在办公室,我在没有编译器的情况下键入了代码。因为它应该说明这个问题,所以编译错误等应该不会太重要
我所说的模型的剥离版本:
public class RegisterToRead : IValueNotifyPropertyChanged
{
...
public bool UseName { get {...} set {...} }
}
我典型的模板选择器之一
public class RegisterToReadTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item,
DependencyObject container)
{
if(item != null && item is RegisterToRead)
{
RegisterToRead register = (RegisterToRead)item;
if( register.UseName)
return element.FindResource("nameSelectionTemplate") as DataTemplate;
else
return element.FindResource("manualEntryTemplate") as DataTemplate;
}
return null;
}
}
我不能做,但在精神上想做
有一个如下所示的模板选择器
:
public class BooleanTemplateSelector : DataTemplateSelector
{
public property DataTemplate TrueTemplate { get; set; }
public property DataTemplate FalseTemplate { get; set; }
public override DataTemplate SelectTemplate(object item,
DependencyObject container)
{
if(item != null && item is bool)
{
bool value = (bool)item;
if( value)
return TrueTemplate;
else
return FalseTemplate;
}
return null;
}
}
并这样使用,以达到上述效果:
<sel:BooleanTemplateSelector
TrueTemplate="{StaticResource nameSelectionTemplate}"
FalseTemplate="{StaticResource manualEntryTemplate}"
x:Key="RegisterToReadTemplateSelector" />
<ContentPresenter Content="{Binding SelectedRegister.UseName}"
ContentTemplateSelector={StaticResource ResourceKey=RegisterToReadTemplateSelector}"/>