Стилизация ошибки проверки в WPF DataGridCell - PullRequest
1 голос
/ 30 сентября 2010

Я пытаюсь изменить способ отображения DataGridCell, если он содержит ошибки. По умолчанию он имеет белый фон и красную рамку при обнаружении ошибки. Однако, похоже, что мои попытки установить Validation.ErrorTemplate этого класса игнорируются, как и мои триггеры для свойства Validation.HasError. Весь код, необходимый для воспроизведения проблемы, находится ниже; Я был полностью неспособен заставить WPF применять любые стили к ячейке при ошибке. Кто-нибудь видит проблему здесь или есть потенциальный обходной путь?

app.xaml

<Application.Resources>
        <ControlTemplate x:Key="ErrorTemplate">
            <DockPanel>
                <TextBlock Text="Busted!"/>
                <AdornedElementPlaceholder/>
            </DockPanel>
        </ControlTemplate>
        <Style x:Key="{x:Type WpfToolkit:DataGridCell}" TargetType="{x:Type WpfToolkit:DataGridCell}">
            <Style.Setters>
                <Setter Property="Validation.ErrorTemplate" Value="{StaticResource ErrorTemplate}"/>
                <Setter Property="Background" Value="Green"/>
            </Style.Setters>
            <Style.Triggers>
                <Trigger Property="Validation.HasError" Value="True">
                    <Setter Property="Background" Value="Red"/>
                    <Setter Property="ToolTip" Value="Doh!"/>
                </Trigger>
            </Style.Triggers>

        </Style>
    </Application.Resources>

MainWindow.xaml

<Grid>

        <WpfToolkit:DataGrid ItemsSource="{Binding Path=MyItems, ValidatesOnDataErrors=True}" AutoGenerateColumns="False">
            <WpfToolkit:DataGrid.Columns>
                <WpfToolkit:DataGridTextColumn Header="Wheel Count" Binding="{Binding WheelCount, ValidatesOnDataErrors=True}"/>
                <WpfToolkit:DataGridTextColumn Header="Car Colour" Binding="{Binding Color, ValidatesOnDataErrors=True}"/>
            </WpfToolkit:DataGrid.Columns>
        </WpfToolkit:DataGrid>
    </Grid>

Класс, к которому привязан класс

Car.cs

class Car : IDataErrorInfo, INotifyPropertyChanged
    {
        public Car(int numWheels, string Color)
        {
            _color = Color;
            _wheelCount = numWheels;
        }

        private string _color;
        public string Color
        {
            get
            {
                return _color;
            }
            set
            {
                _color = value;
                if (value.Length > 10)
                {
                    //Warning
                }
                if (value.Length > 20)
                {
                    //Error
                }
                PropChanged("Color");

            }
        }

        private int _wheelCount;
        public int WheelCount
        {
            get
            {
                return _wheelCount;
            }
            set
            {
                _wheelCount = value;
                if (value != 4)
                {
                    AddError("WheelCount", "There should be 4 wheels on the car!");
                }
                else
                    this.ClearError("WheelCount");
                PropChanged("WheelCount");

            }
        }

        public void AddError(string propName, string errorMessage)
        {
            if (myErrors.ContainsKey(propName))
                myErrors.Remove(propName);
            myErrors.Add(propName, errorMessage);
            PropChanged(propName);
            PropChanged("Error");
        }

        public void ClearError(string propName)
        {
            if (myErrors.ContainsKey(propName))
                myErrors.Remove(propName);
        }

        private Dictionary<string, string> myErrors = new Dictionary<string, string>();

        public string Error
        {
            get
            {
                StringBuilder myError = new StringBuilder("Errors");
                foreach (KeyValuePair<string,string> currentErr in myErrors)
                {
                    myError.AppendLine(currentErr.Key + ":" + currentErr.Value);
                }
                return myError.ToString();
            }
        }

        public string this[string columnName]
        {
            get
            {
                if (!myErrors.ContainsKey(columnName))
                    return null;
                else
                    return myErrors[columnName];
            }
        }

        public void PropChanged(string propName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

"ViewModel" для представления - CarVM:

CarVM.cs

 class CarVM
    {
        public CarVM()
        {
            for (int currentCar = 0; currentCar < 20; currentCar++)
            {
                myCars.Add(new Car(4, "Red"));
            }
            MyItems = (CollectionView)CollectionViewSource.GetDefaultView(myCars);
        }
        private List<Car> myCars = new List<Car>();
        public CollectionView MyItems
        {
            get;
            private set;
        }
    }

А код в окне очень прост:

MainWindow.xaml.cs

 public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new CarVM();
        }
    }

Ответы [ 3 ]

2 голосов
/ 30 сентября 2010

Столбцы DataGrid сложно стилизовать, поскольку DataContext - это не то, что вы ожидаете во время его создания и применения стиля.См. эту статью , в частности «Использование DataGridColumn.ElementStyle и DataGridColumn.EditingElementStyle для установки свойств содержимого ячейки».

0 голосов
/ 30 сентября 2010

Это потому, что ошибки не генерируются!Ошибки будут добавлены, когда вы назначите Color & WheelCount, а не _color & _wheelCount.Вы никогда ничего не назначаете этим свойствам.

Измените конструктор следующим образом:

public Car(int numWheels, string color)
{
    Color = color;
    WheelCount = numWheels;
}

В случае, если вы даже не видите начальный зеленый цвет, единственная причина, по которой я могудумаю, это действие по сборке вашего файла App.xaml.Убедитесь, что это ApplicationDefinition.

0 голосов
/ 30 сентября 2010

Вместо AddError не могли бы вы попробовать throw new ArgumentException, чтобы подтвердить?

Это следующее условие не выполняется? Не в количестве колес и цвете

        for (int currentCar = 0; currentCar < 20; currentCar++)
        {
            myCars.Add(new Car(4, "Red"));
        }

НТН

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...