我有一个属性是数据库数据类型(char,datetime,int,float等...),我想更改用于输入所选类型值的控件.所以对于文本值我想要一个TextBox和我想要的日期值DatePicker.
我想到的一种方法是在我的表单上Visibility使用每个控件之一并使用适当的IValueConverter实现来设置它们.我知道这会起作用,但它会产生很多代码并且感觉不太好.
我想其他的方法是使用一个ContentPresenter,并将其与内容Style和DataTriggers,但我不能得到它的工作.
<Style x:Key="TypedValueHelper" TargetType="{x:Type ContentPresenter}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=DataType}" Value="Char">
<Setter Property="Content" Value="???"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=DataType}" Value="Date">
<Setter Property="Content" Value="???"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=DataType}" Value="Integer">
<Setter Property="Content" Value="???"/>
</DataTrigger>
</Style.Triggers>
</Style>
Run Code Online (Sandbox Code Playgroud)
如果有人可以填写我的"???" 或者提供更好的解决方案.
Tho*_*son 12
您可以将样式与setter和datatemplates结合使用.你基本上在代码中有了它的开头,虽然我不认为ContentPresenter是正确的样式控件,因为它没有模板.
可能是这样的:
<Style x:Key="TypedValueHelper" TargetType="{x:Type ContentControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=DataType}" Value="Char">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBox Text="{Binding Path=.}" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=DataType}" Value="Integer">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Slider Maximum="100" Minimum="0" Value="{Binding Path=.}"
Orientation="Horizontal" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
Run Code Online (Sandbox Code Playgroud)
...
<ContentControl Content="{Binding MyValue}"
Style="{StaticResource TypedValueHelper}">
Run Code Online (Sandbox Code Playgroud)
Boj*_* Li 10
虽然Style解决方案可能有效,但实现动态内容行为的正确方法是使用DataTemplates,如Sdry建议的那样.但是,您将使用枚举来确定要使用的DataTemplate; 这实际上意味着您希望将单个类型映射到多个DataTemplates.DataTemplateSelector类解决了这个问题,以下描述直接来自MSDN:
"通常,如果对同一类型的对象有多个DataTemplate,并且想要提供自己的逻辑来根据每个数据对象的属性选择要应用的DataTemplate,则可以创建DataTemplateSelector."
您应该通过ContentControl托管动态内容,如下所示:
<ContentControl Content="{Binding Path=ReferenceToYourViewModel}" ContentTemplateSelector="{DynamicResource MyTemplateSelector}"/>
Run Code Online (Sandbox Code Playgroud)
MyTemplateSelector的实现:
public class MyTemplateSelector: DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
FrameworkElement elem = container as FrameworkElement;
if(elem == null)
{
return null;
}
if (item == null || !(item is YourViewModel))
{
throw new ApplicationException();
}
if ((item as YourViewModel).DataType == DataType.Char)
{
return elem.FindResource("CharDataTemplate") as DataTemplate;
}
if ((item as YourViewModel).DataType == DataType.Date)
{
return elem.FindResource("DateDataTemplate") as DataTemplate;
}
if ((item as YourViewModel).DataType == DataType.Integer)
{
return elem.FindResource("IntegerDataTemplate") as DataTemplate;
}
throw new ApplicationException();
}
}
Run Code Online (Sandbox Code Playgroud)
然后如您所料,这里是可供选择的DataTemplates:
<DataTemplate x:Key="CharDataTemplate" DataType="{x:Type YourViewModel}">Put Your Xaml Here</DataTemplate>
<DataTemplate x:Key="DateDataTemplate" DataType="{x:Type YourViewModel}">Put Your Xaml Here</DataTemplate>
<DataTemplate x:Key="IntegerDataTemplate" DataType="{x:Type YourViewModel}">Put Your Xaml Here</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
这样,将根据View Model的DataType属性选择适当的DataTemplate.在我看来,这比使用Visibility或Styles要清晰得多.
| 归档时间: |
|
| 查看次数: |
10636 次 |
| 最近记录: |