WPF MVVM 创建动态控件
Posted
技术标签:
【中文标题】WPF MVVM 创建动态控件【英文标题】:WPF MVVM Creating Dynamic controls 【发布时间】:2011-07-13 04:18:43 【问题描述】:- 我有一个网格,在上面我有一份工作(你可以说类似 sql server 工作)的详细信息。
现在,对于每个工作,可能有“n”个工作变量。当我获取作业的记录时,它会获取作业变量的集合,这些变量是名称-值对,其中值可以是集合或日期时间值,甚至是 int 或字符串。
现在我想在这里实现的是: -- 如果运行变量是日期时间,那么我需要一个日期选择器 -- 如果是 int/String 我需要一个文本框 - 如果它是一个集合,那么一个组合框。 -- 它是一个位字段,然后是一个复选框
我不确定如何实现它,因为这些值可能因每项工作而异。
【问题讨论】:
【参考方案1】:我假设您将通过设置ItemsSource
属性将代表这些名称/值对的某种对象放入ItemsControl
。
您可以使用多种解决方案。
将DataTemplate
与触发器一起使用:
此方法涉及通过YourPropertyType
属性将每个对象的“类型”作为字符串公开。您将把ItemsControl
的ItemTemplate
设置为承载ContentControl
的模板。 ContentControl
本身将通过触发器动态选择其 ContentTemplate
。
所有这些都可以在 XAML 中以声明方式完成。
我假设您还有更多 DataTemplates
命名为 DefaultTemplate
(这可以是空的)、IntegerTemplate
、StringTemplate
等来为每个案例勾勒出可视化树。
这将是ItemsControl.ItemTemplate
:
<DataTemplate>
<ContentControl
x:Name="MyContentControl"
Content="Binding"
ContentTemplate="StaticResource DefaultTemplate"/>
<DataTemplate.Triggers>
<DataTrigger Binding="Binding YourPropertyType" Value="Integer">
<Setter TargetName="MyContentControl" Property="ContentTemplate"
Value="StaticResource IntegerTemplate" />
</DataTrigger>
<DataTrigger Binding="Binding YourPropertyType" Value="String">
<Setter TargetName="MyContentControl" Property="ContentTemplate"
Value="StaticResource StringTemplate" />
</DataTrigger>
<!-- and so on -->
</DataTemplate.Triggers>
</DataTemplate>
使用DataTemplateSelector
:
这种方法需要代码隐藏,但它不会强制您将每个名称/值对的“类型”公开为字符串,它允许您选择使用哪个模板来处理更复杂的逻辑。
它涉及创建一个类作为模板选择器:
class YourObjectDataTemplateSelector : DataTemplateSelector
public DataTemplate DefaultTemplate get; set;
public override DataTemplate SelectTemplate(object item, DependencyObject container)
var yourObject = (YourObjectType) item;
// Get hold of a DataTemplate based on any attribute of item
var templateToUse = this.DefaultTemplate;
return templateToUse;
然后,您需要在某处实例化一个模板选择器(假设在您的 UserControl
内部)
<UserControl.Resources>
<localNamespace:YourObjectDataTemplateSelector
x:Key="TemplateSelector"
DefaultTemplate="StaticResource DefaultTemplate"
/>
</UserControl.Resources>
请注意,我从 YourObjectDataTemplateSelector
公开了一个 DefaultTemplate
属性并将其设置为来自 XAML 的模板。在实践中,您将在YourObjectDataTemplateSelector
上定义更多DataTemplate
类型的属性,并在将模板选择器添加到控件的资源字典时“配置”它。这允许您使用来自 XAML 的 StaticResource
标记扩展直接为每个案例设置模板。
最后,将模板选择器连接到您的ItemsControl
:
<ItemsControl
ItemsSource="..."
ItemTemplateSelector=StaticResource TemplateSelector"
/>
【讨论】:
【参考方案2】:我相信您正在考虑使用某种形式的 Data Templating 和 DataTemplateSelector 来实现您所追求的目标。
【讨论】:
以上是关于WPF MVVM 创建动态控件的主要内容,如果未能解决你的问题,请参考以下文章
WPF随笔之 控件根据设定的显示行数列数填充控件并自适应窗体大小(多绑定MVVM方式实现)