有条件地为所有项目选择 ComboBox ItemTemplate

发布于 2024-12-13 18:32:35 字数 4946 浏览 1 评论 0原文

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

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

John Doe
1234 假圣钱德勒,亚利桑那州
(480) 555-2342

如果您将其更改为最后/第一位,则客户将在下拉列表中显示为:

Doe、John
1234 假圣钱德勒,亚利桑那州
(480) 555-2342

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

[电子邮件受保护]
约翰·多伊
1234 Fake St. Chandler, Az

我知道如何编写模板,但如何根据第一个 ComboBox 的选择设置第二个 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>

I have a form with two ComboBoxes. The second ComboBox holds a list of customers. The first ComboBox lets the user choose how they want to search for Customers and see them displayed. Currently, someone has it running different stored procedures for each search type just to change the way it's displayed in the drop down. I would like to change it so that it chooses a DataTemplate based on the selection of the first drop down.

E.G. If you choose First/Last from the first ComboBox, the customers will display in the second ComboBox drop down as:

John Doe
1234 Fake St. Chandler, Az
(480) 555-2342

If you change it to Last/First, the customers will then show in the drop down as:

Doe, John
1234 Fake St. Chandler, Az
(480) 555-2342

Or if you choose Email, it would display as:

[email protected]
John Doe
1234 Fake St. Chandler, Az

I know how to write the templates, but how do I set the second ComboBox.ItemTemplate based on the selection of the first ComboBox? I'd be fine with using Triggers or C# code.

EDIT: Here is one attempt I just tried, but the template doesn't change. I know the trigger is working because the background turns green.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

┼── 2024-12-20 18:32:35

您可以像这样使用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 的 依赖属性优先级 规则,直接在标记中定义的值覆盖任何样式或触发值。要使触发模板生效,请在 ComboBox 的 Style 中设置默认的 ItemTemplate

You can use a DataTrigger like this:

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

Edit

Just noticed the edit to your question. The problem with what you have is the ItemTemplate is defined in the <ComboBox /> tag. According to WPF's Dependency Property Precedence rules, a value defined directly in the tag overwrites any Styled or Triggered values. To make the Trigged template take effect, set the default ItemTemplate in your ComboBox's Style

画尸师 2024-12-20 18:32:35

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

You can use ItemTemplateSelector. It will choose the right template for you based on selection in first ComboBox.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文