C# 为什么ComboBox最初不显示IsSelected==true的ComboBoxItem?

C# 为什么ComboBox最初不显示IsSelected==true的ComboBoxItem?,c#,wpf,combobox,C#,Wpf,Combobox,在下面的代码中,为什么属性为IsSelected设置为true的项目不在组合框中被选中,就像单击按钮后在列表框中被选中一样? 单击组合框后,所选项目将变为选中,但不会在之前。 xaml: <Window x:Class="WpfApplication1.Desktop.Shell" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schem

在下面的代码中,为什么属性为
IsSelected
设置为
true
的项目不在
组合框中被选中,就像单击
按钮后在
列表框中被选中一样?

单击
组合框
后,所选项目将变为选中,但不会在之前。

xaml:

<Window x:Class="WpfApplication1.Desktop.Shell"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="350" Width="525">
    <StackPanel>
        <ListBox ItemsSource="{Binding Items}">
            <ListBox.Resources>
                <Style TargetType="ListBoxItem">
                    <Setter Property="IsSelected" 
                            Value="{Binding Path=IsSelected, Mode=TwoWay}" />
                </Style>
            </ListBox.Resources>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Label Content="{Binding Txt}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <ComboBox ItemsSource="{Binding Items}">
            <ComboBox.Resources>
                <Style TargetType="ComboBoxItem">
                    <Setter Property="IsSelected" 
                            Value="{Binding Path=IsSelected, Mode=TwoWay}" />
                </Style>
            </ComboBox.Resources>
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Label Content="{Binding Txt}" />
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
        <Button Content="Select second item" Click="Button_Click"  />
    </StackPanel>
</Window>
using System.Collections.ObjectModel;
using System.ComponentModel.Composition;
using System.Windows;
using Microsoft.Practices.Prism.ViewModel;

namespace WpfApplication1.Desktop
{
    [Export]
    public partial class Shell : Window
    {
        public class Foo : NotificationObject
        {
            static int _seq = 0;
            string _txt = "Item " + (++_seq).ToString();
            public string Txt { get { return _txt; } }
            bool _isSelected;
            public bool IsSelected
            {
                get { return _isSelected; }
                set
                {
                    _isSelected = value; 
                    RaisePropertyChanged(() => IsSelected);
                }
            }
        }

        public ObservableCollection<Foo> Items { get; set; }

        public Shell()
        {
            Items = new ObservableCollection<Foo>();
            for (int i = 0; i < 5; i++)
                Items.Add(new Foo());
            DataContext = this;
            InitializeComponent();
        }

        void Button_Click(object sender, RoutedEventArgs e)
        {
            Items[1].IsSelected = true;
        }
    }
}

xaml.cs:

<Window x:Class="WpfApplication1.Desktop.Shell"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="350" Width="525">
    <StackPanel>
        <ListBox ItemsSource="{Binding Items}">
            <ListBox.Resources>
                <Style TargetType="ListBoxItem">
                    <Setter Property="IsSelected" 
                            Value="{Binding Path=IsSelected, Mode=TwoWay}" />
                </Style>
            </ListBox.Resources>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Label Content="{Binding Txt}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <ComboBox ItemsSource="{Binding Items}">
            <ComboBox.Resources>
                <Style TargetType="ComboBoxItem">
                    <Setter Property="IsSelected" 
                            Value="{Binding Path=IsSelected, Mode=TwoWay}" />
                </Style>
            </ComboBox.Resources>
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Label Content="{Binding Txt}" />
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
        <Button Content="Select second item" Click="Button_Click"  />
    </StackPanel>
</Window>
using System.Collections.ObjectModel;
using System.ComponentModel.Composition;
using System.Windows;
using Microsoft.Practices.Prism.ViewModel;

namespace WpfApplication1.Desktop
{
    [Export]
    public partial class Shell : Window
    {
        public class Foo : NotificationObject
        {
            static int _seq = 0;
            string _txt = "Item " + (++_seq).ToString();
            public string Txt { get { return _txt; } }
            bool _isSelected;
            public bool IsSelected
            {
                get { return _isSelected; }
                set
                {
                    _isSelected = value; 
                    RaisePropertyChanged(() => IsSelected);
                }
            }
        }

        public ObservableCollection<Foo> Items { get; set; }

        public Shell()
        {
            Items = new ObservableCollection<Foo>();
            for (int i = 0; i < 5; i++)
                Items.Add(new Foo());
            DataContext = this;
            InitializeComponent();
        }

        void Button_Click(object sender, RoutedEventArgs e)
        {
            Items[1].IsSelected = true;
        }
    }
}
使用System.Collections.ObjectModel;
使用System.ComponentModel.Composition;
使用System.Windows;
使用Microsoft.Practices.Prism.ViewModel;
命名空间WpfApplication1.Desktop
{
[出口]
公共部分类外壳:窗口
{
公共类Foo:NotificationObject
{
静态整数_seq=0;
字符串_txt=“Item”+(++).ToString();
公共字符串Txt{get{return}
布尔乌当选;
公选学校
{
获取{return}isSelected;}
设置
{
_isSelected=值;
RaisePropertyChanged(()=>IsSelected);
}
}
}
公共ObservableCollection项{get;set;}
公共Shell()
{
Items=新的ObservableCollection();
对于(int i=0;i<5;i++)
添加(新的Foo());
DataContext=this;
初始化组件();
}
无效按钮\单击(对象发送器,路由目标)
{
项[1]。IsSelected=true;
}
}
}

当使用模型作为WPF窗口的
DataContext
时,控件最初的行为可能与您预期的不同。本质上,一些属性/事件直到初始化窗口后才被设置/调用。本例中的解决方法是在窗口的
Loaded
事件中设置绑定


免责声明:我没有用OP的特定场景对此进行测试,但这是我在过去遇到的行为和解决方法。

当使用模型作为WPF窗口的
DataContext
时,控件最初的行为可能与您预期的不同。本质上,一些属性/事件直到初始化窗口后才被设置/调用。本例中的解决方法是在窗口的
Loaded
事件中设置绑定


免责声明:我没有在OP的特定场景中对此进行测试,但这是我在过去遇到的行为和解决方法。

由于绑定默认设置为
UpdateSourceTrigger=LostFocus
,因此您必须将其更改为
PropertyChanged
,以获得所需的结果。 像这样:

<Style TargetType="ListBoxItem">
  <Setter Property="IsSelected"Value="{Binding Path=IsSelected, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
</Style>

由于绑定默认设置为
UpdateSourceTrigger=LostFocus
,因此必须将其更改为
PropertyChanged
,才能获得所需的结果。 像这样:

<Style TargetType="ListBoxItem">
  <Setter Property="IsSelected"Value="{Binding Path=IsSelected, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
</Style>

这是因为ItemContainerStyle仅在生成ComboBoxItems时应用(即打开下拉列表时)

要解决这个问题,您需要创建另一个名为SelectedItem的属性,并将组合框的SelectedValue绑定到该属性


这是因为只有在生成ComboBoxItems时(即打开下拉列表时),才会应用ItemContainerStyle

要解决这个问题,您需要创建另一个名为SelectedItem的属性,并将组合框的SelectedValue绑定到该属性


在代码中,您更改了ListBoxItem的绑定,但问题在于ComboBoxItem;我尝试更改ComboBoxItem的绑定,但问题仍然存在;我尝试更改ComboBoxItem的绑定,但问题仍然存在。