滚动时数据网格挂起/冻结

时间:2012-04-10 04:11:17

标签: wpf mvvm datagrid

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

Person ListViewModel

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

1 个答案:

答案 0 :(得分:0)

不要在IDataErrorInfo中执行耗时的IO操作[string columnName] Getter。使

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

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