Hallo Leute,
ich versuche gerade der HeaderColumn des DataGrids ein Command zu geben, aber ich komme nicht weiter und bräuchte mal eure Hilfe.
Ich verwende folgenden XML-Code:
<DataGrid
x:Name="dgFileContent"
Grid.Row="1"
AutoGenerateColumns="True"
CanUserSortColumns="False"
CanUserReorderColumns="True"
AllowDrop="True"
HeadersVisibility="{Binding HeaderVisibility, Mode=TwoWay}"
ItemsSource="{Binding FileDataTable, Mode=TwoWay}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Drop">
<i:InvokeCommandAction Command="{Binding DropCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="IsHitTestVisible" Value="False"/>
</Style>
</DataGrid.Resources>
<DataGridColumnHeader>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding HeaderClickCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGridColumnHeader>
</DataGrid>
Es wird hier eine Datei per Drag&Drop eingefügt, was soweit auch wunderbar funktioniert.
Allerdings wenn ich den Bereich <DataGridColumnHeader> einfüge, dann bekomme ich folgende Fehlermeldung:
"Die Items-Sammlung muss vor dem Verwenden von "ItemsSource" leer sein."
Das ViewModel hat folgende Deklarationen für das Command, was jetzt aber mit dem Fehler nichts zu tun hat:
public ICommand HeaderClickCommand
{
get
{
if (_headerClickCommand == null)
_headerClickCommand = new RelayCommand(param => this.HeaderClick(param), param => this.CanHeaderClick());
return _headerClickCommand;
}
}
public bool CanHeaderClick()
{
return true;
}
public void HeaderClick(object obj)
{
}
Was mache ich falsch bzw. was muss ich machen damit ich auf die HeaderColumns ein Click-Command bekomme?
Kommando zurück!!!
Ich habe gerade festgestellt, dass wenn ich hier:
<i:Interaction.Triggers>
<i:EventTrigger EventName="Drop">
<i:InvokeCommandAction Command="{Binding DropCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="IsHitTestVisible" Value="False"/>
</Style>
</DataGrid.Resources>
noch irgendetwas hinzufüge, also Style z.B. dann wirft es mir auch den Fehler. Der Fehler passiert dann, wenn ich die DataTable der DataTable-Property, also hier:
public DataTable FileDataTable
{
get { return _fileDataTable; }
set
{
_fileDataTable = value;
this.OnPropertyChanged("FileDataTable");
}
}
hinzufüge. Jetzt hab ich gar keinen Plan mehr...
Der Fehler passiert zur Laufzeit, oder?
Hast du noch andere Codestellen (z.B. im Konstruktor), wo du die ItemsSource
setzt (bzw. manuell Items
hinzufügst)?
Hallo Th69,
ja, der Fehler passiert zur Laufzeit.
Ich denke aber dass ich das Problem gefunden habe, und zwar wenn im XML ein ungültiger oder unlogischer Eintrag ist, und der Compiler das nicht erkennt, dann wirft es zur Laufzeit den Fehler. Wobei die Fehlermeldung nichtssagend bezüglich XML ist.
Dein XAML Zeugs existiert nur zur Entwicklungszeit und ist Deine Oberfläche als Entwickler. Der Compiler macht daraus Quellcode, weshalb Du auch eine xaml.cs-Datei hast. Ab diesem Zeitpunkt ist Deine XAML technisch ein BAML.
Der Compiler spielt hier also gar nicht mehr mit, sondern vereinfacht ausgedrückt nur noch die Runtime.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hallo Abt,
wie auch immer. Der Fehler tritt nur dann auf wie ich das mit dem XML beschrieben habe.
Allerdings ist meine Hauptfrage nicht beantwortet, wie ich der HeaderColumn ein Click Command geben kann.
Mein letzter Versuch den ich gemacht habe ist über den folgenden ColumnHeaderStyle. Als Test ob er das Template auch nimmt, habe ich dem Button ein ToolTip gegeben, und der zeigt mir das auch an. Es werden aber weder Background, Foreground oder eben der Click gemacht.
Hier der Style:
<Window.Resources>
<Style x:Key="ColumnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridColumnHeader">
<Grid>
<Button Content="{TemplateBinding Content}" ToolTip="Blubb">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<i:InvokeCommandAction Command="{Binding ClickCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
Hier das DataGrid
<DataGrid
x:Name="dgFileContent"
Grid.Row="1"
AutoGenerateColumns="True"
CanUserSortColumns="False"
CanUserReorderColumns="True"
AllowDrop="True"
ColumnHeaderStyle="{DynamicResource ColumnHeaderStyle}"
ItemsSource="{Binding FileDataTable.DefaultView}">
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="IsHitTestVisible" Value="False"/>
</Style>
</DataGrid.Resources>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Drop">
<i:InvokeCommandAction Command="{Binding DropCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGrid>
Hab das Problem gelöst. Danke für eure Hilfe.
Das Problem war, dass er die komplette Pfadangabe haben wollte.