查看我的代码,我意识到我的许多DataTemplateSelector
基于类的功能几乎相同,例如检查bool
绑定对象的属性。我真的不想要一堆几乎做同样事情的对象,但我对我的想法并不完全满意。
我最喜欢的想法是将我需要的对象绑定到模板,并让我DataTemplateSelector
有一个属性可以设置为例如布尔属性的名称,该属性应该用于选择模板(在实例化选择器时提供名称)我的 xaml。在选择器中,我将使用反射来访问该属性。
第二个想法是只绑定我的布尔属性,然后在我的模板中使用与祖先的相对绑定DataContext
并从那里开始工作。我不喜欢这样,因为它看起来非常违反直觉并且难以维护。
我可以为此目的实现一个接口(以便布尔属性始终具有相同的名称),但这意味着我将在模型中包含一些仅用于视图的代码。或者在 a 中实现接口,ViewModel
并且不能DataTemplateSelector
在同一个控件中进行多个操作(不为此目的拆分为类)。
只需按名称绑定即可。非常简单的解决方案,但如果您想在多个控件中重用您的模板,则实际上并不能正常工作。如果我有一个UserControl
我需要模板的地方,我会选择的解决方案。只需将其作为资源,UserControl
并拥有一个简单且可维护的解决方案。只要您不想在多个控件中使用模板,那绝对没有问题。
还有其他我忽略的想法吗?对上面列出的事情有任何意见吗?
用于说明的示例代码
注意:因为我不在办公室,所以我在没有编译器的情况下输入了代码。既然它应该说明这个问题,编译错误等应该没有太大关系
我正在谈论的模型的剥离版本:
public class RegisterToRead : IValueNotifyPropertyChanged
{
...
public bool UseName { get {...} set {...} }
}
TemplateSelector
我的典型之一
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;
}
}
我不能做,但精神上想做的事
有一个TemplateSelector
看起来像这样的:
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}"/>
但我不能这样做,因为DataContext
模板内部将设置为 UseName 属性,这不是我想要的。
这个问题在stackoverflow上有一个重复:Bind property for ContentTemplateSelector but pass DataContext to template where the OP没有得到任何答案,并提出了第四个想法。我想重申这个问题,以获得对我发布的其他想法的一些反馈。