2

我有这个绑定到 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 但没有运气。

4

3 回答 3

4

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

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

为此,Selected 属性必须引发 PropertyChanged 事件。

<List.Resources>
    <Style TargetType="ListBoxItem">
        <Setter 
            Property="IsSelected" 
            Value="{Binding 
                        Path=DataContext.Selected, 
                        RelativeSource={RelativeSource Self}}" 
            />
    </Style>
</List.Resources>
于 2008-11-06T21:04:51.603 回答
1

您是否查看过列表框的 SelectedItemChanged 和 SelectedIndexChanged 事件?

每当更改选择时,都应该触发这些,无论它是如何选择的。

于 2008-11-06T13:32:58.117 回答
0

我认为您应该在选择更改时触发 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>

我希望这有帮助。

于 2008-11-06T15:24:03.647 回答