C# 有条件地为所有项目选择组合框ItemTemplate

C# 有条件地为所有项目选择组合框ItemTemplate,c#,wpf,combobox,datatemplate,conditional-formatting,C#,Wpf,Combobox,Datatemplate,Conditional Formatting,我有一张有两个组合框的表格。第二个组合框包含客户列表。第一个组合框允许用户选择如何搜索客户并查看其显示。目前,有人让它为每种搜索类型运行不同的存储过程,只是为了更改它在下拉列表中的显示方式。我想更改它,以便它根据第一个下拉列表的选择选择DataTemplate 例如,如果从第一个组合框中选择First/Last,则客户将在第二个组合框下拉列表中显示为: 无名氏 1234亚利桑那州假圣钱德勒 (480)555-2342 如果将其更改为Last/First,则客户将在下拉列表中显示为: 多伊,约翰

我有一张有两个组合框的表格。第二个组合框包含客户列表。第一个组合框允许用户选择如何搜索客户并查看其显示。目前,有人让它为每种搜索类型运行不同的存储过程,只是为了更改它在下拉列表中的显示方式。我想更改它,以便它根据第一个下拉列表的选择选择DataTemplate

例如,如果从第一个组合框中选择First/Last,则客户将在第二个组合框下拉列表中显示为:

无名氏
1234亚利桑那州假圣钱德勒
(480)555-2342

如果将其更改为Last/First,则客户将在下拉列表中显示为:

多伊,约翰
1234亚利桑那州假圣钱德勒
(480)555-2342

或者,如果您选择电子邮件,它将显示为:

JDoe@gmail.com
无名氏
1234亚利桑那州假圣钱德勒

我知道如何编写模板,但如何根据第一个组合框的选择设置第二个ComboBox.ItemTemplate?我可以使用触发器或C代码

编辑:这是我刚刚尝试过的一次尝试,但模板没有改变。我知道触发器正在工作,因为背景变成绿色

<UserControl.Resources>
    <DataTemplate x:Key="ComboBoxCustomTemplate">
        <Grid Margin="3 3">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <TextBlock Grid.Row="0" Grid.ColumnSpan="2" Text="{Binding Name}" />
            <WrapPanel Grid.Row="1" Orientation="Horizontal">
                <TextBlock Text="Address:" />
                <TextBlock HorizontalAlignment="Left" Foreground="#003366" Margin="3,0,0,0" Text="{Binding Address}" />
            </WrapPanel>
            <WrapPanel Grid.Row="2" Orientation="Horizontal">
                <TextBlock Text="Phone:" />
            <TextBlock HorizontalAlignment="Left" Foreground="#003366" Margin="3,0,0,0" Text="{Binding Telephone}" />
            </WrapPanel>                                
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="ComboBoxEmailTemplate">
        <Grid Margin="3 3">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <TextBlock Grid.Row="0" Grid.ColumnSpan="2" Text="{Binding Email}" />
            <WrapPanel Grid.Row="1" Orientation="Horizontal">
                <TextBlock Text="Address:" />
                <TextBlock HorizontalAlignment="Left" Foreground="#003366" Margin="3,0,0,0" Text="{Binding Address}" />
            </WrapPanel>
            <WrapPanel Grid.Row="2" Orientation="Horizontal">
                <TextBlock Text="Phone:" />
                <TextBlock HorizontalAlignment="Left" Foreground="#003366" Margin="3,0,0,0" Text="{Binding Telephone}" />
            </WrapPanel>
        </Grid>
    </DataTemplate>
</UserControl.Resources>

<ComboBox Name="cbSearchFilter" Padding="5,1" Width="150" Margin="3,3,10,3" SelectionChanged="cbSearchFilter_SelectionChanged" Style="{StaticResource VirtualizingComboBox}">
            <ComboBoxItem Content="Parent Last/First" Tag="LastFirst" />
            <ComboBoxItem Content="Parent First/Last" Tag="FirstLast" />
            <ComboBoxItem Content="Student First/Last" Tag="Student" IsSelected="True" />
            <ComboBoxItem Content="Parent Phone Number" Tag="PhoneNumber"/>
            <ComboBoxItem Content="Parent Email" Tag="Email"/>
        </ComboBox>

<ComboBox Name="cbCustomers"
                SelectedValuePath="FamilyID"
                ItemTemplate="{StaticResource ComboBoxCustomTemplate}"
                Grid.Column="1" Grid.Row="2" IsEditable="True" StaysOpenOnEdit="True"
                KeyboardNavigation.IsTabStop="False" SelectionChanged="rcbCustomers_SelectionChanged" KeyUp="rcbCustomers_KeyUp" KeyDown="rcbCustomers_KeyDown" >
            <ComboBox.Style>
                <Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource VirtualizingComboBox}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding ElementName=cbSearchFilter, Path=SelectedItem.Tag}" Value="Email">
                            <DataTrigger.Setters>
                                <Setter Property="Background" Value="Green" />
                                <Setter Property="ItemTemplate" Value="{StaticResource ComboBoxEmailTemplate}" />
                            </DataTrigger.Setters>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ComboBox.Style>
        </ComboBox>

您可以使用。它将根据第一个组合框中的选择为您选择正确的模板。

您可以使用如下
DataTrigger

<Style x:Key="ComboBox2Style">
    <Setter Property="ItemTemplate" Value="{StaticResource DefaultTemplate}" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding SelectedValue, ElementName=ComboBox1}" Value="LastFirst">
            <Setter Property="ItemTemplate" Value="{StaticResource LastNameFirstTemplate}" />
        </DataTrigger>
        <DataTrigger Binding="{Binding SelectedValue, ElementName=ComboBox1}" Value="Email">
            <Setter Property="ItemTemplate" Value="{StaticResource EmailTemplate}" />
        </DataTrigger>
    </Style.Triggers>
</Style>

编辑


刚刚注意到对你的问题的编辑。您所遇到的问题是
ItemTemplate
是在
标记中定义的。根据WPF的规则,直接在标记中定义的值将覆盖任何样式化或触发的值。要使触发的模板生效,请在组合框的
样式中设置默认的
ItemTemplate

您熟悉
DataTemplateSelector
类和MVVM模式吗?我在这里描述了单个视图的类似行为:,但ComboBox类在某种程度上有所不同。实现正确的数据模板和视图模型,然后发布代码,这样我就更容易回答了。谢谢Vortex。我正在查看DataTemplateSelector,但我的印象是,这是一个逐项选择模板的过程;其中,条件基于被绑定项的一个或多个属性。其中,我希望对条件为另一个组合框的选定值的所有项目使用相同的模板。我不熟悉MVVP模式,所以我不确定我是否了解您。customers组合框当前正绑定到DataView。但是,不管我已经拥有了什么,我只是希望根据另一个控件的值设置ItemTemplate。好的,正确视图模型的实现需要很多时间,所以我不会坚持重写代码。在当前xaml代码中,
DataTrigger
无法覆盖现有属性。尝试使用
DataTrigger.EnterActions
ObjectAnimationUsingKeyFrame
来设置
ItemTemplate
。我正在查看,但是如何访问ItemTemplateSelector中第一个组合框的值?@xr280xr如果使用MVVM模式,您可以观察父视图模型中的组合框更改,并更新子集合中的所有项。比如
this.Customers.ForEach(c=>c.ViewType==View.FirstLast)
感谢Rachel,感谢您的操作和编辑。这就是诀窍!