user610650
user610650

Reputation:

Why does ComboBox not initially show the ComboBoxItem with IsSelected==true?

In the following code, why doesn't the item with property IsSelected set to true become selected in the ComboBox just as it does in the ListBox after clicking the Button? enter image description here

Once I click on the ComboBox, the selected item becomes selected, but not before. enter image description here

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>

xaml.cs:

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

Upvotes: 0

Views: 1462

Answers (3)

17 of 26
17 of 26

Reputation: 27382

It's because the ItemContainerStyle is applied only when the ComboBoxItems are generated (i.e. when you open the dropdown).

To work around this, you create another property called SelectedItem and bind the Combobox's SelectedValue to it.

Long explanation and example here

Upvotes: 3

shriek
shriek

Reputation: 5197

Because the binding is set on UpdateSourceTrigger=LostFocus by default, you would have to change it to PropertyChanged to get the result you want. Like this:

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

Upvotes: 1

Metro Smurf
Metro Smurf

Reputation: 38335

When using a Model as the DataContext for a WPF Window, the Controls may not initially behave as you'd expect. Essentially, some properties/events never get set/called until after the Window been initialized. The work-around in this case is to setup the binding in the Window's Loaded event.

Disclaimer: I have not tested this with the OP's specific scenario, but this is the behavior and work-around I've encountered in the past.

Upvotes: 0

Related Questions