WPF 列表视图 SelectionChanged 事件

发布于 2024-08-03 10:38:21 字数 156 浏览 4 评论 0原文

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

我怎样才能禁用这个功能?

I have a ListView binding to an ItemsSource and the SelectionChanged event is firing on the load/databound events? I assume that it is because a 'default' items ie index 0 is selected.

How can I disable this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

秋意浓 2024-08-10 10:38:21

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

当页面加载时,这不会触发 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() 之前)。

希望这有帮助。

The listView should not fire the SelectionChange if you only set the ItemsSource property. However if you bind the SelectedIndex property to a property of your dataContext object the selection will move to the index that is specified by the binded property.

this doesn't fires the Selector_OnSelectionChanged event when the page loads:

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

but this does:

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

because the SelectedIndex is set to the SelecteIndexValue through binding.

To avoid this and still keep the bindings in your markup set the SelectedIndexValue of your dataContext object to -1 before binding (Before InitializeComponent() is called in your form constructor).

Hope this helps.

再浓的妆也掩不了殇 2024-08-10 10:38:21

感谢您的回复。

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

在我的 SelectionChanged 事件中,您可以看到,我通知其他对象加载与所选项目相关的数据。我只希望在选择一个而不是设置默认值时发生这种情况。我必须使用这些代表相似数据的 ListView,但在加载时都必须选择一个项目。

我注意到列表视图的属性窗口中默认的选定索引设置为 -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);
    }

我添加了 PreviewMouseDown 来设置一个指示器,指示我已单击 SelectionChanged 事件中的列表视图。这确实有帮助,但我不相信这是最好的解决方案。

谢谢
帕特鲁斯

thanks for the responses.

When I put a breakpoint on the SelectionChanged event, it breaks proceedings there before the screen is fully loaded. You will also see that the first row is 'selected' afterwards on the list. I am not binding to a SelectedIndexValue as you can see in the code. The DataContext for the list is a ReadonlyCollection

In my SelectionChanged event as you can see I notify other objects to be loaded with data relating to the selected item. I only want this to happen when one is selected but not a default one to be set. I have to of these ListViews representing similar data but on loaded none must have an item selected.

I have noticed that the default Selected index is set to -1 on the properties window for the Listview. I can even set this is code on the List_Loaded event, but by then the first SelectionChanged has happened already.

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

I added the PreviewMouseDown to set an indicator that I have clicked on the listview in the SelectionChanged event. This does help but I'm not convinced that its the best solution.

Thanks
Petrus

躲猫猫 2024-08-10 10:38:21

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

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

I don't know if you still need help with this, but I solved this problem by making a variable that tracks the selectedindex, in my case -- when initially bound it's always 0 so it's a little easier for me to do, however if you inform the viewmodel of the appropriate index, I simply added a

ComboBox box = e.OriginalSource as ComboBox;
if (_previousIndex == cb.SelectedIndex) return;
//do stuff you need to do with a new SelectedIndex
倾`听者〃 2024-08-10 10:38:21

您可以尝试在绑定中将 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 集合的类型是什么?

You can try to set the SelectedIndex property to -1 in your binding but this also is not an elegant solution.

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

I tried to reproduce your behavior but without success.
What is the Type of the ItemsSource collection that you are binding to?

初懵 2024-08-10 10:38:21

您可以使用窗口加载事件来阻止操作

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 ....

}

you can use window loaded event to block the action

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 ....

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文