每当ItemsSource更改时,如何将ComboBox的SelectedIndex设置为零?

时间:2013-05-25 14:10:08

标签: wpf styles master-detail

这应该很简单,但我找不到它: 我有两个通过Master-Detail Binding相关的组合框:

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

当我在第一个组合框中选择一个项目时,第二个组合框会被适当的播放列表填充,但我想自动选择它的第一个项目。

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

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

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

怎么做?

2 个答案:

答案 0 :(得分:3)

您可以使用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" 

答案 1 :(得分:3)

老实说,最好/最简单的方法是在ViewModel中,当一个的SelectedIndex改变时,翻转所需的Property(另一个的selectedInex)绑定将完成剩下的工作。 不需要样式,触发器和整个混乱。但是为了好玩,这只是一个快速的'脏',所以发布整个/大多数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";
    }

在我的代码后面创建了一个ViewModel,它包含了List1,List2,SelectedItemList1等所有属性。所以绑定就可以了。如果您需要ViewModel代码(省略它,显而易见......),请告诉我。

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