WPF列表视图选择更改事件

14

我有一个绑定到ItemsSourceListView,并且在加载/数据绑定事件上触发SelectionChanged事件。 我认为这是因为选择了“默认”的项,即索引0。

如何禁用这个行为?


嗨,Petrus。你能分享一下你的代码吗? - Anvaka
5个回答

8

如果您只设置ItemsSource属性,listView不应该触发SelectionChange。但是,如果将SelectedIndex属性绑定到数据上下文对象的属性,则选择将移动到绑定属性指定的索引。

当页面加载时,这不会触发Selector_OnSelectionChanged事件:

<ListView SelectionChanged="Selector_OnSelectionChanged" 
                  ItemsSource="{Binding Path=Items}"
                  ></ListView>

但是这个可以:
<ListView SelectionChanged="Selector_OnSelectionChanged" 
                  SelectedIndex="{Binding Path=SelectedIndexValue}"
                  ItemsSource="{Binding Path=Items}"
                  ></ListView>

因为SelectedIndex通过绑定设置为SelecteIndexValue。

为了避免这种情况,同时保持标记中的绑定,请在绑定之前将dataContext对象的SelectedIndexValue设置为-1(在窗体构造函数中调用InitializeComponent()之前)。

希望这可以帮助您。


1

我不知道你是否仍需要关于这个的帮助,但是我通过创建一个跟踪所选索引的变量来解决了这个问题,在我的情况下--当最初绑定时它总是为0,所以这对我来说更容易,然而如果你通知视图模型适当的索引,我只需添加一个


ComboBox box = e.OriginalSource as ComboBox;
if (_previousIndex == cb.SelectedIndex) return;
//do stuff you need to do with a new SelectedIndex

1

感谢回复。

当我在SelectionChanged事件上设置断点时,它会在屏幕完全加载之前中断。您还将看到列表中的第一行之后被“选中”。正如您在代码中所看到的,我没有绑定到SelectedIndexValue。列表的DataContext是一个ReadonlyCollection。

在我的SelectionChanged事件中,正如您所看到的,我通知其他对象加载与所选项目相关的数据。我只希望在选择一个项目但不设置默认项目时才发生这种情况。我有两个表示类似数据的ListView,但在加载时都不能有任何项目被选中。

我注意到Listview的属性窗口中默认的Selected index设置为-1。我甚至可以在List_Loaded事件中在代码中设置它,但那时第一个SelectionChanged已经发生了。

<ListView PreviewMouseDown="ActiveCasesView_MouseDown" x:Name="ActiveCasesView"
                     DataContext="{StaticResource ActiveCasesViewSource}"
                     ItemsSource="{Binding}"
                     ItemTemplate="{StaticResource CasesItemTemplate}"
                     SelectionMode="Single"
                     SelectionChanged="ActiveCasesView_SelectionChanged"
                     ScrollViewer.CanContentScroll="True" 
                     ScrollViewer.VerticalScrollBarVisibility="Auto" >
</ListView>

private void ActiveCasesView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (mouseClicked)
            if (e.AddedItems.Count > 0)
                App.Messenger.NotifyColleagues(App.MSG_SELECT_ACTIVE_CASE, ((CaseViewModel)ActiveCasesView.SelectedItem).CaseNumber);
    }

我在SelectionChanged事件中添加了PreviewMouseDown以设置指示器,表示我已单击了listview。这确实有所帮助,但我并不确定它是最佳解决方案。
谢谢 Petrus

0

你可以尝试在绑定中将SelectedIndex属性设置为-1,但这也不是一种优雅的解决方案。

<ListView PreviewMouseDown="ActiveCasesView_MouseDown" x:Name="ActiveCasesView"
                     DataContext="{StaticResource ActiveCasesViewSource}"
                     ItemsSource="{Binding}"
                     ItemTemplate="{StaticResource CasesItemTemplate}"
                     SelectionMode="Single"
                     SelectionChanged="ActiveCasesView_SelectionChanged"
                     ScrollViewer.CanContentScroll="True" 
                     ScrollViewer.VerticalScrollBarVisibility="Auto" 
**SelectedIndex="-1"**>
</ListView>

我尝试复现您的行为,但没有成功。 您绑定到的ItemsSource集合的类型是什么?


我正在绑定到一个自定义ViewModel的ReadonlyCollection<T>。 - Petrus

0
你可以使用窗口加载事件来阻止操作。
bool loaded = false;

window.Loaded += new RoutedEventHandler(MainWindow_Loaded);

void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
   windowLoaded = true;
}

private void ActiveCasesView_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{

if(!loaded)
return ;

//do actions here ....

}

在这种情况下,第一项可以是不可点击的。 - Vitalii Vasylenko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接