WPF 绑定在短时间使用后自发失败

发布于 2024-10-03 22:49:59 字数 3310 浏览 0 评论 0原文

如果要编译并运行以下代码,您会发现选择和/或取消选择一行会导致将一行写入输出窗口(因为仔细检查所述代码会让人相信)。

使用箭头键更改网格的选定行一小段时间后(分别按住向上和向下箭头以遍历整个数据集几次),人们会震惊(就像我一样)注意到输出消息停止,即使继续循环网格的行。

我试图实现类似于这个答案中给出的内容。

我绝对感到困惑。什么会导致网格上的绑定自发失败?非常感谢这里的任何和所有帮助!另外,如果有人有时间重现此内容,请评论您的发现。

XAML:

<Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
    <Grid>
        <DataGrid Name="TheGrid">
            <DataGrid.Resources>
                <Style TargetType="{x:Type DataGridRow}">
                    <Setter Property="IsSelected" 
                            Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
                </Style>
            </DataGrid.Resources>
            <DataGrid.Columns>
                <DataGridTextColumn IsReadOnly="True" 
                                    Binding="{Binding Name}" Header="Name"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

代码隐藏:

using System;
using System.ComponentModel;
using System.Linq;
using System.Windows;

namespace WpfApplication1 {
    public partial class Window1 : Window {
        public Window1() {
            InitializeComponent();
            TheGrid.ItemsSource = Enumerable.Range(1, 100)
                                 .Select(i => new MyClass("Item " + i));
        }
    }

    public class MyClass : INotifyPropertyChanged {
        public string Name { get; private set; }

        private bool m_IsSelected;
        public bool IsSelected {
            get {
                return m_IsSelected;
            }
            set {
                if (m_IsSelected != value) {
                    m_IsSelected = value;
                    Console.WriteLine(Name + ": " + m_IsSelected);
                    PropertyChanged(this, 
                        new PropertyChangedEventArgs("IsSelected"));
                }
            }
        }

        public MyClass(string name) {
            Name = name;
        }

        public event PropertyChangedEventHandler PropertyChanged = 
                                                            delegate { };
    }
}

提前致谢!

编辑:

  • 尝试应用DataGridRow 使用 RowStyleSelector 的样式 属性 - 失败。

  • 尝试使用 Row_LoadingRow_Unloading 事件应用 DataGridRow 样式 - 失败。

  • 尝试使用自定义MultiSelectCollectionView - 失败(不适用于 DataGrid 控件)

  • 尝试设置 VirtualizingStackPanel.IsVirtualizing="False" - 失败(无法使用)数百行速度慢)

  • 尝试弄乱VirtualizingStackPanel.VirtualizationMode code>(标准或回收)- 失败。

正如我下面的评论之一所述,首要问题是我需要将 DataGrid 的 SelectedItems 属性绑定到我的 ViewModel,但不能,因为 SelectedItems 是只读的。

是某种纯 MVVM、开箱即用的解决方案,但到目前为止,我还没有想到!

If one were to compile and run the following code, one would find that selecting and/or deselecting a row causes a line to be written to the Output window (as closer inspection of said code would lead one to believe).

After a short time of changing the selected row of the grid using the arrow keys (holding the Up and Down arrows respectively to traverse the entire data set a few times), one would be shocked (as I was) to notice that Output messages cease, even while continuing to cycle through the grid's rows.

I am attempting to achieve something similar to what was given in this answer.

I am absolutely baffled. What would cause Bindings on my grid to spontaneously fail? Any and all help here would be MUCH appreciated!! Also, should anyone have the time to reproduce this, please comment with your findings.

XAML:

<Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
    <Grid>
        <DataGrid Name="TheGrid">
            <DataGrid.Resources>
                <Style TargetType="{x:Type DataGridRow}">
                    <Setter Property="IsSelected" 
                            Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
                </Style>
            </DataGrid.Resources>
            <DataGrid.Columns>
                <DataGridTextColumn IsReadOnly="True" 
                                    Binding="{Binding Name}" Header="Name"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

Code-behind:

using System;
using System.ComponentModel;
using System.Linq;
using System.Windows;

namespace WpfApplication1 {
    public partial class Window1 : Window {
        public Window1() {
            InitializeComponent();
            TheGrid.ItemsSource = Enumerable.Range(1, 100)
                                 .Select(i => new MyClass("Item " + i));
        }
    }

    public class MyClass : INotifyPropertyChanged {
        public string Name { get; private set; }

        private bool m_IsSelected;
        public bool IsSelected {
            get {
                return m_IsSelected;
            }
            set {
                if (m_IsSelected != value) {
                    m_IsSelected = value;
                    Console.WriteLine(Name + ": " + m_IsSelected);
                    PropertyChanged(this, 
                        new PropertyChangedEventArgs("IsSelected"));
                }
            }
        }

        public MyClass(string name) {
            Name = name;
        }

        public event PropertyChangedEventHandler PropertyChanged = 
                                                            delegate { };
    }
}

Thanks in advance!

EDIT:

  • Tried applying the DataGridRow
    Style using the RowStyleSelector
    property - fail.

  • Tried applying the DataGridRow Style using the Row_Loading and Row_Unloading events - fail.

  • Tried using a custom MultiSelectCollectionView - fail (didn't work with DataGrid control)

  • Tried setting VirtualizingStackPanel.IsVirtualizing="False"- fail (unusably slow with hundreds of rows)

  • Tried messing with VirtualizingStackPanel.VirtualizationMode (Standard or Recycled) - fail.

As stated in one of my comments below, the overarching problem is that I need to bind the SelectedItems property of the DataGrid to my ViewModel, but can't, since SelectedItems is read-only.

There HAS to be some kind of pure-MVVM, out-of-the-box solution for this, but so far, it eludes me!

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

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

发布评论

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

评论(1

街道布景 2024-10-10 22:49:59

我刚刚尝试过这个并且有相同的行为。我能够通过更改 DataGrid 以防止其虚拟化来解决该问题,如下所示:

有关详细信息,请参阅此 MSDN 论坛帖子< /a>.

I just tried this and had the same behavior. I was able to fix the problem by changing the DataGrid to prevent it from virtualizing as follows: <DataGrid Name="TheGrid" AutoGenerateColumns="False" VirtualizingStackPanel.IsVirtualizing="False">.

For more information see this MSDN forum post.

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