如何同步ListBox的SelectedItem?

时间:2008-11-06 13:26:30

标签: c# wpf listbox

我有一个绑定到ObservableCollection的ListBox。列表中的每个对象都实现一个名为ISelectable

的接口
public interface ISelectable : INotifyPropertyChanged
{
    event EventHandler IsSelected;
    bool Selected { get; set; }
    string DisplayText { get; }
}

我想跟踪哪个对象被选中,无论它是如何被选中的。用户可以单击ListBox中对象的表示,但也可以通过代码选择对象。如果用户通过ListBox选择一个对象,我将所选项目转换为ISelectable并将Selected属性设置为true。

ISelectable selectable = (ISelectable)e.AddedItems[0];
selectable.Selected = true;

我的问题是,当我使用代码选择对象时,我无法获取ListBox来更改所选项目。我正在使用DataTemplate以不同的颜色显示所选对象,这意味着所有内容都正确显示。但是ListBox具有用户单击的最后一个对象作为SelectedItem,这意味着如果没有先在列表中选择另一个对象,则无法单击该项。

任何人都知道如何解决这个问题?我非常确定通过编写一些自定义代码来处理鼠标和键盘事件,我可以完成我想要的工作,但我不愿意。我已经尝试将SelectedItem属性添加到集合并将其绑定到ListBox的SelectItemProperty但没有运气。

3 个答案:

答案 0 :(得分:4)

您也可以通过将ListBoxItem.IsSelected数据绑定到Selected属性来完成此操作。我们的想法是在创建每个ListBoxItem时为其设置绑定。这可以使用针对ListBox生成的每个ListBoxItem的样式来完成。

这样,当选择/取消选择ListBox中的项目时,将更新相应的Selected属性。同样,在代码中设置Selected属性将反映在ListBox

要使其工作,Selected属性必须引发PropertyChanged事件。

<List.Resources>
    <Style TargetType="ListBoxItem">
        <Setter 
            Property="IsSelected" 
            Value="{Binding 
                        Path=DataContext.Selected, 
                        RelativeSource={RelativeSource Self}}" 
            />
    </Style>
</List.Resources>

答案 1 :(得分:1)

你看过列表框的SelectedItemChanged和SelectedIndexChanged事件吗?

无论选择方式如何,只要选择更改,就应触发这些选项。

答案 2 :(得分:0)

我认为你应该在select更改时触发propertyChanged事件。将此代码添加到实现ISelectable的对象。你最终会得到类似的东西:

private bool _Selected;
        public bool Selected
        {
            get
            {
                return _Selected;
            }
            set
            {
                if (PropertyChanged != null)                
                    PropertyChanged(this, new PropertyChangedEventArgs("Selected"));

                _Selected = value;
            }
        }

我尝试过以下代码:

public ObservableCollection<testClass> tests = new ObservableCollection<testClass>();

        public Window1()
        {
            InitializeComponent();
            tests.Add(new testClass("Row 1"));
            tests.Add(new testClass("Row 2"));
            tests.Add(new testClass("Row 3"));
            tests.Add(new testClass("Row 4"));
            tests.Add(new testClass("Row 5"));
            tests.Add(new testClass("Row 6"));
            TheList.ItemsSource = tests;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            tests[3].Selected = true;
            TheList.SelectedItem = tests[3];
        }

其中testClass实现了ISelectable。

这是一片xaml,没什么特别的:

<ListBox Grid.Row="0" x:Name="TheList"></ListBox>        
<Button Grid.Row="1" Click="Button_Click">Select 4th</Button>

我希望这会有所帮助。