基于选择在运行时加载控件



我是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>

值得注意的观点是

  1. DataContext在Window元素上初始化,允许在绑定表达式上自动完成
  2. 定义2个模板以显示2个不同的数据视图
  3. 组合框由字符串列表填充,并默认选择第一个元素
  4. ContentControl将其内容绑定到通过ViewModel公开的模型
  5. 默认的DataTemplate是第一个具有ComboBox的模板
  6. 如果组合框的SelectedItem更改为"Template 2",则ContentControl样式中的触发器将更改ContentTemplate

隐含的事实是

  1. 如果SelectedItem变回"Template 1",样式将把ContentTemplate恢复为默认值,即MyModel1Template1
  2. 如果需要3个单独的显示,请创建另一个DataTemplate,向ComboBox添加一个字符串,然后添加另一个数据触发器

注意:这是我的示例的完整来源。用相同的类创建一个新的C#/WPF项目,并通过中的代码。它应该可以工作

我希望这能有所帮助。

最新更新