【问题标题】:Conditionally Choose ComboBox ItemTemplate for all Items有条件地为所有项目选择 ComboBox ItemTemplate
【发布时间】:2011-12-22 07:25:10
【问题描述】:

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

例如如果您从第一个 ComboBox 中选择 First/Last,则客户将在第二个 ComboBox 下拉菜单中显示为:

约翰·多伊
1234 Fake St. Chandler, AZ
(480) 555-2342

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

多伊,约翰
1234 Fake St. Chandler, AZ
(480) 555-2342

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

JDoe@gmail.com
约翰·多伊
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>

【问题讨论】:

  • 您熟悉DataTemplateSelector 类和MVVM 模式吗?我在这里为单个视图描述了类似的行为:stackoverflow.com/questions/5309099/…,但 ComboBox 类在某种程度上有所不同。实现正确的数据模板和视图模型,然后发布代码,然后我会更容易回答。
  • 感谢 vorrtex。我正在查看 DataTemplateSelector,但我的印象是,这是用于逐项选择模板;其中条件基于被绑定项目的一个或多个属性。我想对条件是另一个 ComboBox 的选定值的所有项目使用相同的模板。我不熟悉 MVVP 模式,所以我不确定我是否在关注你。客户 ComboBox 当前只是绑定到 DataView。但不管我已经拥有什么,我真的只是想根据另一个控件的值来设置 ItemTemplate。
  • 好的,正确的视图模型的实现需要很多时间,所以我不会坚持重写代码。在您当前的 xaml 代码中,DataTrigger 无法覆盖现有属性。尝试使用DataTrigger.EnterActionsObjectAnimationUsingKeyFrame 来设置ItemTemplate

标签: c# wpf combobox datatemplate conditional-formatting


【解决方案1】:

您可以像这样使用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 是在&lt;ComboBox /&gt; 标记中定义的。根据 WPF 的Dependency Property Precedence 规则,直接在标记中定义的值会覆盖任何样式或触发值。要使触发模板生效,请在您的 ComboBox 的Style 中设置默认的ItemTemplate

【讨论】:

  • 感谢 Rachel,您的 OP 和编辑。这样就行了!
【解决方案2】:

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

【讨论】:

  • 我在看,但是如何访问 ItemTemplateSelector 中第一个 ComboBox 的值?
  • @xr280xr 如果您使用 MVVM 模式,您可以观察父视图模型中的组合框更改并更新子集合中的所有项目。喜欢this.Customers.ForEach(c =&gt; c.ViewType == View.FirstLast)
猜你喜欢
  • 1970-01-01
  • 2018-12-12
  • 1970-01-01
  • 2020-10-04
  • 2012-09-06
  • 2011-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多