【问题标题】:Datagrid hang/ freezes when scroll滚动时Datagrid挂起/冻结
【发布时间】:2012-04-10 04:11:17
【问题描述】:

我对 WPF 中的数据网格有一个奇怪的问题。我正在为我的应用程序使用 MVVM 模式,并且我的视图模型实现了 idataerrorinfo 接口。每当我在添加新行后在我的数据网格中上下滚动时,所有单元格都会混杂在一起,整个数据网格都会冻结。如果我删除 idataerrorinfo 接口实现,它工作正常。有人有同样的问题吗?

.任何帮助将不胜感激...

更新: 只有在我向 dataGrid 添加新行后才会出现奇怪的行为。如果我正在修改现有行并上下滚动不会导致任何问题。将新视图模型添加到我的可观察集合时发生了一些事情。不知道是什么。需要帮助..

更新: 这是该项目的一个小版本 XAML

<Window x:Class="testWPF.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:dg="http://schemas.microsoft.com/wpf/2008/toolkit"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>

    <!-- style to apply to DataGridTextColumn in edit mode  -->
    <Style x:Key="CellEditStyle" TargetType="{x:Type TextBox}">
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="Padding" Value="0"/>
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="ToolTip"
                        Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
            </Trigger>
        </Style.Triggers>
    </Style>

    <!-- A Row Style which renders a different validation error indicator -->
    <Style x:Key="RowStyle" TargetType="{x:Type dg:DataGridRow}">
        <Setter Property="ValidationErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <Grid>
                        <Ellipse Width="12" Height="12" Fill="Red" Stroke="Black" StrokeThickness="0.5"/>
                        <TextBlock FontWeight="Bold" Padding="4,0,0,0" Margin="0" VerticalAlignment="Top" Foreground="White" Text="!"
                                   ToolTip="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type dg:DataGridRow}},
                                                     Path=(Validation.Errors)[0].ErrorContent}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<!-- a simple details view which is synchronised with the selected item in the data grid -->

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="265*" />
        <RowDefinition Height="46*" />
    </Grid.RowDefinitions>
    <DataGrid Name="dataGrid" AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="True"
              ItemsSource="{Binding GetPeople}" Height="204" Margin="0,54,0,8">
        <!--<dg:DataGrid.RowValidationRules>
            <local:RowDummyValidation/>
        </dg:DataGrid.RowValidationRules>-->
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" EditingElementStyle="{StaticResource CellEditStyle}"
                                Binding="{Binding Path=Name, ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}"/>
            <DataGridTextColumn Header="Age" EditingElementStyle="{StaticResource CellEditStyle}"
                                Binding="{Binding Path=Age, ValidatesOnExceptions=True}"/>
        </DataGrid.Columns>
    </DataGrid>
    <Button Content="Button" Command="{Binding AddNewConfigProperty}"
            Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="194,11,0,0"
            Name="button1" VerticalAlignment="Top" Width="75" />
</Grid>

人员列表视图模型

namespace testWPF
{
    class PersonListViewModel: ViewModelBase
    {
        private ObservableCollection<Person> personCollection;

        //private PartNumbersEntities dbCOntext = new PartNumbersEntities();
        public ObservableCollection<Person> GetPeople
        {
            get
            {
                if (personCollection == null)
                {
                    personCollection = new ObservableCollection<Person>();
                    for(int i= 0; i<100;i++)
                    {
                        personCollection.Add(new Person()
                        {
                            Name = "Frank Grimmes",
                            Age = 25,
                            DateOfBirth = new DateTime(1975, 2, 19)
                        });
                    }
                }                  
                return personCollection;
            }             
        }

        public ICommand AddNewConfigProperty { get { return new RelayCommand(AddNewConfigPropertyExecute, CanAddNewConfigPropertyExecute); } }

        bool CanAddNewConfigPropertyExecute()
        {
            return true;
        }

        void AddNewConfigPropertyExecute()
        {
            personCollection.Add(new Person()
                    {
                        Name = "Some Name",
                        Age = 25,
                        DateOfBirth = new DateTime(1924, 9, 1)
                    });
            OnPropertyChanged("GetPeople");
        }  
    }
}

人物类

namespace testWPF
{
    public class Person : ViewModelBase, IDataErrorInfo
    {
        //private readonly Regex nameEx = new Regex(@"^[A-Za-z ]+$");

        private string name;

        public string Name
        {
            get { return name; }
            set
            { 
                name = value;
            }
        }

        private int age;

        public int Age
        {
            get { return age; }
            set
            {
                age = value;
            }
        }

        public DateTime DateOfBirth { get; set; }

        public string Error
        {
            get { return ""; }
        }

        public string this[string columnName]
        {
            get
            {
                string result = null;
                if (columnName == "Name")
                {
                    if (string.IsNullOrEmpty(Name))
                        result = "Please enter a name";
                }
                return result;
            }
        } 
    } 
}

【问题讨论】:

    标签: wpf mvvm datagrid


    【解决方案1】:

    不要在 IDataErrorInfo this[string columnName] Getter 中进行耗时的 IO 操作。制作

    System.IO.File.AppendAllText("C:\\temp\\log.txt", "PartConfigName: " + PartConfigName + "\r\n");
    

    asynchronconditional on debug modus [Conditional("DEBUG")]

    【讨论】:

    • 我已经删除了那个 IO 操作部分。但是仍然有同样的错误。实际上我只是把它放在那里检查控制进入验证的次数......现在我有一些新发现......请检查更新部分。
    • AddNewConfigPropertyExecute() 中有两个AllConfig.Add(),也许这就是问题所在。 PS:为了快速检查,我使用Console.Write()
    • 对不起,额外的 AllConfig.Add()。我已经摆脱了它。但没有解决我的问题。我创建了一个微型项目,不包括所有实体框架的东西。但是仍然有同样的问题。只有当我添加一行并尝试编辑和滚动时才会发生这种情况。收藏发生了一些事情。不知道是什么。如果你喜欢我可以把代码发给你。
    • 不需要AddNewConfigPropertyExecute() OnPropertyChanged("GetPeople");。 ObservableCollection 负责处理新项目。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-28
    相关资源
    最近更新 更多