Hallo,
ich habe folgendes Datagrid:
<DataGrid x:Name="tagsGrid" ItemsSource="{Binding}" GridLinesVisibility="Vertical" AlternatingRowBackground="#C3DDE5"
AutoGenerateColumns="False" CanUserAddRows="True" IsReadOnly="False"
SelectionUnit="Cell" SelectionMode="Extended" BorderThickness="3" RowStyle="{StaticResource RawTagDataGridRow}">
<DataGrid.Columns>
<DataGridTextColumn x:Name="TagName" Header="Tag" Width="*" KeyboardNavigation.TabIndex="1"
Binding="{Binding Mode=TwoWay, Path=RawTag.TagName, UpdateSourceTrigger=PropertyChanged, ValidatesOnNotifyDataErrors=True, NotifyOnValidationError=True}"
ElementStyle="{StaticResource ResourceKey=textBlockErrStyle}" />
<DataGridTextColumn x:Name="TagCycle" Header="Cycle" KeyboardNavigation.TabIndex="2"
Binding="{Binding Mode=TwoWay, Path=RawTag.Cycle, UpdateSourceTrigger=PropertyChanged, ValidatesOnNotifyDataErrors=True, NotifyOnValidationError=True}"
ElementStyle="{StaticResource ResourceKey=textBlockErrStyle}"/>
<DataGridTextColumn x:Name="TagSource" Header="Source" Width="*" KeyboardNavigation.TabIndex="3"
Binding="{Binding Mode=TwoWay, Path=RawTag.Source, UpdateSourceTrigger=PropertyChanged, ValidatesOnNotifyDataErrors=True, NotifyOnValidationError=True}"
ElementStyle="{StaticResource ResourceKey=textBlockErrStyle}"/>
<DataGridTextColumn x:Name="Unassigned" Header="unassigned" Width="*" KeyboardNavigation.TabIndex="4"
Binding="{Binding Mode=OneWay, Path=RawTag.Unassigned, UpdateSourceTrigger=PropertyChanged, ValidatesOnNotifyDataErrors=False}"
ElementStyle="{StaticResource ResourceKey=textBlockUnassignedStyle}"/>
<DataGridTemplateColumn x:Name="editTagColumn" Header="" CanUserResize="True" KeyboardNavigation.TabIndex="5">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<WrapPanel>
<Button x:Name="btnTagDelete" Click="BtnTagDelete_Click" CommandParameter="{Binding}" Height="15" Width="15" Margin="2">
<Button.Content>
<Image Source="../Resources/delete.png"></Image>
</Button.Content>
</Button>
</WrapPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
der verwendete RawTagDataGridRow - Style sieht folgendermaßen aus:
<Style x:Key="RawTagDataGridRow" TargetType="{x:Type DataGridRow}">
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontFamily" Value="ArialMT"/>
<Setter Property="Height" Value="Auto"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(Validation.HasError), RelativeSource={RelativeSource Self}}" Value="true" >
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="IsEnabled" Value="True" />
<Setter Property="ValidationErrorTemplate">
<Setter.Value>
<ControlTemplate>
<Grid>
<Border BorderBrush="red" BorderThickness="1" Background="#11FF0000" Opacity="0.5" IsHitTestVisible="False" x:Name="errorBorder"/>
<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 RawTag.GetAllErrors}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=(Validation.HasError), RelativeSource={RelativeSource Self}}" Value="false" >
<Setter Property="ToolTip" Value="{x:Null}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="Green"/>
<Setter Property="IsEnabled" Value="True" />
<Setter Property="ValidationErrorTemplate" Value="{x:Null}" />
</DataTrigger>
</Style.Triggers>
</Style>
der verwendete textBlockErrStyle - Style
<Style x:Key="textBlockErrStyle" TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(Validation.HasError), RelativeSource={RelativeSource Self}}" Value="false" >
<Setter Property="ToolTip" Value="{x:Null}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=(Validation.HasError), RelativeSource={RelativeSource Self}}" Value="true" >
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="White" />
<Setter Property="ToolTip" >
<Setter.Value>
<MultiBinding Converter="{StaticResource SimpleErrorConverter}">
<Binding Path="." RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridRow}" />
<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=DataGridCell}" Path="Column"/>
</MultiBinding>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
die im Viewmodel enthaltene Instanz Klasse RawTag implementiert INotifyDataErrorInfo
public Dictionary<string, List<string>> ErrorList = new Dictionary<string, List<string>>();
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
public void NotifyErrorsChanged(string propertyName)
{
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
}
public bool HasErrors
{
get
{
return ErrorList.Count > 0;
}
}
public void AddError(string propertyName, string error)
{
if (ErrorList.ContainsKey(propertyName))
{
if (!ErrorList[propertyName].Contains(error))
{
ErrorList[propertyName].Add(error);
}
}
else
{
ErrorList[propertyName] = new List<string>() { error };
}
NotifyErrorsChanged(propertyName);
}
public void RemoveError(string propertyName)
{
if (ErrorList.ContainsKey(propertyName))
{
ErrorList.Remove(propertyName);
NotifyErrorsChanged(propertyName);
}
}
public IEnumerable GetErrors(string propertyName)
{
ErrorList.TryGetValue(propertyName, out List<string> errorsForName);
if (propertyName != "GetAllErrors")
{
OnPropertyChanged("GetAllErrors");
}
return errorsForName;
}
public string GetAllErrors
{
get
{
if (!HasErrors)
{
return null;
}
int count = 1;
var errorString = "Errors:";
foreach (var e in ErrorList)
{
e.Value.ForEach(v => errorString += Environment.NewLine + count++ + ". " + v);
}
return errorString;
}
}
die letzte Methode wird für den Tooltip der Row genutzt.
In den Properties wird das Interface verwendet, Bsp:
public string TagName
{
get => tagName;
set
{
if (value == tagName)
{
return;
}
tagName = value;
RemoveError("TagName");
if (TagName.Contains(";"))
{
AddError("TagName", "TagName may not contain the character ';'.");
}
if (TagName.Trim().Equals("?"))
{
AddError("TagName", "'?' is not a valid value for TagName");
}
OnPropertyChanged();
}
}
Nun zu meinem Problem:
Ich habe keine Ahnung, wo ich noch schauen kann.
Was habe ich vergessen / übersehen?
Viele Grüße und vielen Dank
Dirk