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