我是XAML的新手,有一种情况需要根据带有模板的组合框上的选择来更改控件。
例如,假设用户选择一个模板,该模板需要一周中的某一天和某个可用的时间范围。我希望,在选择的那一刻,带有所需信息的控件就可以在屏幕上构建,绑定也可以工作。
有人能给我一个提示或用优雅的方式指出一篇文章吗?
提前谢谢。
您正在寻找的解决方案是ContentControl和DataTemplates。您可以使用组合框的选定项来更改内容控件的ContentTemplate。
您的问题提到绑定,所以我假设您了解MVVM模式。
例如,让我们使用MyModel1作为模型
public class MyModel1
{
private Collection<string> values;
public Collection<string> Values { get { return values ?? (values = new Collection<string> { "One", "Two" }); } }
public string Field1 { get; set; }
public string Field2 { get; set; }
}
将MyViewModel作为ViewModel
public class MyViewModel
{
public MyViewModel()
{
Model = new MyModel1();
}
public MyModel1 Model { get; set; }
}
而后面的代码只是实例化ViewModel。
public partial class MainWindow : Window
{
public MainWindow()
{
ViewModel = new MyViewModel();
InitializeComponent();
}
public MyViewModel ViewModel { get; set; }
}
这三类都是非常简单的类。乐趣来自Xaml,它是
<Window x:Class="StackOverflow._20893945.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:this="clr-namespace:StackOverflow._20893945"
DataContext="{Binding RelativeSource={RelativeSource Self}, Path=ViewModel}"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate x:Key="MyModel1Template1" DataType="{x:Type this:MyModel1}">
<StackPanel>
<TextBlock Text="Template 1"></TextBlock>
<ComboBox ItemsSource="{Binding Path=Values}" SelectedItem="{Binding Path=Field1}" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="MyModel1Template2" DataType="{x:Type this:MyModel1}">
<StackPanel>
<TextBlock Text="Template 2"></TextBlock>
<TextBox Text="{Binding Path=Field2}" />
</StackPanel>
</DataTemplate>
</Window.Resources>
<DockPanel>
<StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Margin="2">
<ComboBox x:Name="TypeSelector">
<system:String>Template 1</system:String>
<system:String>Template 2</system:String>
</ComboBox>
</StackPanel>
<ContentControl Content="{Binding Path=Model}">
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=TypeSelector, Path=SelectedItem}" Value="Template 2">
<Setter Property="ContentTemplate" Value="{StaticResource MyModel1Template2}" />
</DataTrigger>
</Style.Triggers>
<Setter Property="ContentTemplate" Value="{StaticResource MyModel1Template1}" />
</Style>
</ContentControl.Style>
</ContentControl>
</DockPanel>
</Window>
值得注意的观点是
- DataContext在Window元素上初始化,允许在绑定表达式上自动完成
- 定义2个模板以显示2个不同的数据视图
- 组合框由字符串列表填充,并默认选择第一个元素
- ContentControl将其内容绑定到通过ViewModel公开的模型
- 默认的DataTemplate是第一个具有ComboBox的模板
- 如果组合框的SelectedItem更改为"Template 2",则ContentControl样式中的触发器将更改ContentTemplate
隐含的事实是
- 如果SelectedItem变回"Template 1",样式将把ContentTemplate恢复为默认值,即MyModel1Template1
- 如果需要3个单独的显示,请创建另一个DataTemplate,向ComboBox添加一个字符串,然后添加另一个数据触发器
注意:这是我的示例的完整来源。用相同的类创建一个新的C#/WPF项目,并通过中的代码。它应该可以工作
我希望这能有所帮助。