【问题标题】:How to set a ComboBox's SelectedIndex to zero whenever its ItemsSource changes?每当其 ItemsSource 更改时,如何将 ComboBox 的 SelectedIndex 设置为零?
【发布时间】:2013-05-20 23:09:01
【问题描述】:

这应该很简单,但我找不到它: 我有两个通过主从绑定相关的组合框:

<ComboBox Style="{StaticResource FixedSelectionCombo}"
          ItemsSource="{Binding ElementName=ControlRoot, Path=Clubs}"
          DisplayMemberPath="Name"
          SelectedItem="{Binding ElementName=ControlRoot,Path=SelectedClub}">
</ComboBox>
<ComboBox Style="{StaticResource FixedSelectionCombo}" 
          ItemsSource="{Binding ElementName=ControlRoot, Path=SelectedClub.PlayerLists}"
          DisplayMemberPath="Name"
          SelectedItem="{Binding ElementName=ControlRoot, Path=SelectedPlayerList}">
</ComboBox>

当我在第一个组合框中选择一个项目时,第二个组合框会填充适当的 PlayerLists,但我希望自动选择它的第一个项目。

这在后面的代码中很容易做到,但我想通过可以放入 ResourceDictionary 的样式来实现这一点。我试过了:

  <Style x:Key="FixedSelectionCombo" TargetType="ComboBox" BasedOn="{StaticResource {x:Type ComboBox}}">
        <Setter Property="SelectedIndex" Value="0"/>
    </Style>

但这仅在第一次有效,而不是在我在第一个组合框中进行新选择之后。

怎么做?

【问题讨论】:

    标签: wpf styles master-detail


    【解决方案1】:

    你可以使用Interaction.Triggers来解决这个问题:

    <ComboBox Style="{StaticResource FixedSelectionCombo}"
              ItemsSource="{Binding ElementName=ControlRoot, Path=Clubs}"
              DisplayMemberPath="Name"
              SelectedItem="{Binding ElementName=ControlRoot,Path=SelectedClub}"
              Name="cbClubs">
    </ComboBox>
    <ComboBox Style="{StaticResource FixedSelectionCombo}" 
              ItemsSource="{Binding ElementName=ControlRoot, Path=SelectedClub.PlayerLists}"
              DisplayMemberPath="Name"
              SelectedItem="{Binding ElementName=ControlRoot, Path=SelectedPlayerList}">
         <i:Interaction.Triggers>
                <i:EventTrigger EventName="SelectionChanged" SourceName="cbClubs">
                    <ei:ChangePropertyAction PropertyName="SelectedIndex" Value="1"/>
                </i:EventTrigger>
         </i:Interaction.Triggers>
    </ComboBox>
    

    必需的命名空间:

    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 
    

    【讨论】:

    • 对不起,这不起作用。我收到“i”命名空间没有这个或那个的各种错误消息。此外,代码依赖于对 Master Combobox 的硬编码引用,这违背了使用可重用样式的目的。
    • +1,我总是忘记交互性,发布不同的解决方案,因为我喜欢谜题:)
    • Dabblernl,要使其正常工作,您必须添加两个引用“Microsoft.Expression.Interactions”和“System.Windows.Interactivity”
    【解决方案2】:

    老实说,最好/最简单的方法是在 ViewModel 中,当一个 SelectedIndex 发生变化时,翻转所需的属性(另一个的 selectedInex)绑定将完成其余工作。 不需要样式、触发器和整个混乱。但是为了好玩,这只是一个快速的'n'脏,所以发布整个/大多数xaml以便它可以复制/粘贴/运行......使用不同的属性名称,因为我想先运行/测试它 请注意,转换器返回一个虚拟字符串,您可以在该字符串上触发样式。

    <Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication2"
        Title="MainWindow" x:Name="window" >
    <Window.Resources>
        <local:IndexConverter x:Key="indexConverter"/>
        <Style x:Key="comboBox2Style">
            <Style.Triggers>
                <DataTrigger Binding="{Binding SelectedList1Item, Converter={StaticResource indexConverter}}" 
                             Value="selectFirstIndexOnAnyPropertyChanged">
                    <Setter Property="ComboBox.SelectedIndex" Value="0"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    
    <StackPanel DataContext="{Binding ElementName=window, Path=ViewModel}">
        <ComboBox ItemsSource="{Binding List1}" SelectedItem="{Binding SelectedList1Item}"/>
        <ComboBox ItemsSource="{Binding List2}" SelectedItem="{Binding SelectedList2Item}"
                  Style="{StaticResource comboBox2Style}"/>
    

    public class IndexConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return "selectFirstIndexOnAnyPropertyChanged";
        }
    

    在我后面的代码中创建了一个具有所有属性 List1、List2、SelectedItemList1 等的 ViewModel。因此绑定可以正常工作。如果您需要 ViewModel 代码,请告诉我(省略它,很明显..)

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            ViewModel = new ViewModel();
            InitializeComponent();
        }
    

    【讨论】:

    • 感谢您为此付出的大量工作。它表明在视图模型或后面的代码中(以重复方式)实现此行为要容易得多。仍然:为什么没有简单的ItemsSourceChanged RoutedEvent 可以触发?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 2020-06-29
    • 2021-09-26
    • 2011-09-01
    相关资源
    最近更新 更多