Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 基于选择在运行时加载控件_Wpf_Silverlight_Xaml - Fatal编程技术网

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

Wpf 基于选择在运行时加载控件,wpf,silverlight,xaml,Wpf,Silverlight,Xaml,我是XAML新手,我有一个案例,我需要根据带有模板的组合框上的选择来更改控件 例如,假设用户选择了一个模板,该模板需要一周中的某一天和某个时间范围,才能提供某些内容。我希望,在选择的那一刻,在屏幕上构建具有所需信息的控件,并且绑定也能正常工作 有人能给我一个提示或指出一个优雅的方式这样做的文章 提前感谢。您正在寻找的解决方案是ContentControl和DataTemplates。您可以使用组合框的选定项更改内容控件的ContentTemplate 您的问题提到绑定,所以我假设您理解MVVM模

我是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; }
}
隐藏的代码只是实例化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
模板2
值得注意的观点是

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

  • 如果SelectedItem变回“Template 1”,则样式会将ContentTemplate恢复为默认值,即MyModel1Template1
  • 如果需要3个单独的显示,请创建另一个DataTemplate,向ComboBox添加一个字符串并添加另一个DataTrigger
  • 注意:这是我的示例的完整源代码。创建一个新的C#/WPF项目,该项目使用相同的类并超过中的代码。它应该会起作用


    我希望这有帮助

    看来正是我需要的,马克,我要试试。谢谢
    <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>