Frage

Ich habe zwei WPF Toolkit DataGrids bekommt, würde Ich mag, so dass, wenn der Benutzer die erste Spalte in dem ersten Gitter ändert die Größe, es ändert die Größe die erste Spalte in dem zweiten Gitter. Ich habe versucht, in dem zweiten Gitter in der entsprechenden Spalte in dem ersten Raster, um die Breite der DataGridColumn Bindung, aber es funktioniert nicht. Ich würde es vorziehen, alle XAML zu verwenden, aber ich bin gut mit hinter als auch unter Verwendung von Code.

<tk:DataGrid Width="100" Height="100">
    <tk:DataGrid.Columns>
        <tk:DataGridTextColumn x:Name="Column1" Width="50"/>
    </tk:DataGrid.Columns>
</tk:DataGrid>
<tk:DataGrid Width="100" Height="100">
    <tk:DataGrid.Columns>
        <tk:DataGridTextColumn x:Name="Column1Copy" Width="{Binding Path=ActualWidth, ElementName=Column1}"/>
    </tk:DataGrid.Columns>
</tk:DataGrid>

Ich habe auch versucht, anstatt Width ActualWidth Bindung, aber weder funktioniert.

Jede Hilfe wird sehr geschätzt.

War es hilfreich?

Lösung

Nun, ich glaube nicht, dass es möglich ist, gerade XAML, aber ich fühle mich immer noch, wie es sollte, weil DataGridColumn von DependencyObject nicht ableiten. Ich habe einen Weg finden, es aber programmatisch zu tun. Ich bin nicht begeistert darüber, aber es funktioniert:

DataGridColumn.WidthProperty.AddValueChanged(upperCol, delegate
{
    if (changing) return;
    changing = true;
    mainCol.Width = upperCol.Width;
    changing = false;
});
DataGridColumn.WidthProperty.AddValueChanged(mainCol, delegate 
{ 
    if (changing) return;
    changing = true;
    upperCol.Width = mainCol.Width; 
    changing = false; 
});

public static void AddValueChanged(this DependencyProperty property, object sourceObject, EventHandler handler)
{
    DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(property, property.OwnerType);
    dpd.AddValueChanged(sourceObject, handler);
}

Andere Tipps

Sie können die DataGrid LayoutUpdated Methode verwenden, um andere Objekte in Bezug auf die Spaltenbreiten zu manipulieren.

private void dataGrid1_LayoutUpdated(object sender, EventArgs e)
{
    for(int i = 0 ; i < dataGrid1.Columns.Count && i < dataGrid2.Columns.Count ; ++i)
        dataGrid2.Columns[i].Width = dataGrid1.Columns[i].ActualWidth;
}

Ich habe versucht, dies:

<tk:DataGrid Width="100" Height="100" x:Name="Grid1" Grid.Column="0">
   <tk:DataGrid.Columns>
      <tk:DataGridTextColumn x:Name="Column1" Width="50"/>
   </tk:DataGrid.Columns>
</tk:DataGrid>
<tk:DataGrid Width="100" Height="100" x:Name="Grid2" Grid.Column="1">
   <tk:DataGrid.Columns>
     <tk:DataGridTextColumn x:Name="Column1Copy" Width="{Binding Mode=TwoWay, Path=Columns[0].ActualWidth, ElementName=Grid1}"/>
     </tk:DataGrid.Columns>
</tk:DataGrid>

Allerdings Es sieht aus wie seit DataGridColumns stammt nicht vom FrameworkElement sondern aus DependencyObject ableiten, auf diese Weise der Bindung ist nicht verfügbar.

Wenn Sie Spalte Width-Eigenschaft in XAML zu binden, in 2 DataGrid als Sie folgendes zu tun haben.

Im ersten DataGrid Namen des DataGridTextColumn:

<DataGrid>
    <DataGrid.Columns>
        <DataGridTextColumn x:Name="Col1"/>
    </DataGrid.Columns>
</DataGrid>

In der zweiten DataGrid ein DiscreteObjectKeyFrame hinzufügen zu der oben genannten Spalte als Ressource zeigt, und verwenden Sie die folgende Binding Eigenschaft Width auf dem DataGridTextColumn Sie wollen „link“:

<DataGrid>
    <DataGrid.Resources>
        <DiscreteObjectKeyFrame x:Key="proxyCol1" Value="{Binding ElementName=Col1}"/>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn  Width="{Binding Path=Value.Width, Mode=TwoWay, Source={StaticResource proxyCol1}}"/>
    </DataGrid.Columns>
</DataGrid>

habe ich eine schnelle Lösung dieses Problem ein angebrachtes Verhalten zu verwenden, inspiriert von Ahmed oben beantworten.

public class DataGridWidthSyncronizerBehavior
{
    public static readonly DependencyProperty SyncronizeWidthWithProperty =
        DependencyProperty.RegisterAttached("SyncronizeWidthWith",
            typeof(DataGrid),
            typeof(DataGridWidthSyncronizerBehavior),
            new UIPropertyMetadata(null, SyncronizeWidthWithChanged));

    public static void SetSyncronizeWidthWith(DependencyObject target, DataGrid value)
    {
        target.SetValue(SyncronizeWidthWithProperty, value);
    }

    public static DataGrid GetSyncronizeWidthWith(DependencyObject target)
    {
        return (DataGrid)target.GetValue(SyncronizeWidthWithProperty);
    }

    private static void SyncronizeWidthWithChanged(DependencyObject obj, DependencyPropertyChangedEventArgs dpargs)
    {
        if (!(obj is DataGrid sourceDataGrid))
            return;

        if (!(sourceDataGrid.GetValue(SyncronizeWidthWithProperty) is DataGrid targetDataGrid))
            return;

        void Handler(object sender, EventArgs e)
        {
            for (var i = 0; i < sourceDataGrid.Columns.Count && i < targetDataGrid.Columns.Count; ++i)
                targetDataGrid.Columns[i].Width = sourceDataGrid.Columns[i].ActualWidth;
        }

        sourceDataGrid.LayoutUpdated -= Handler;
        sourceDataGrid.LayoutUpdated += Handler;
    }
}

XAML:

<DataGrid local:DataGridWidthSyncronizerBehavior.SyncronizeWidthWith="{Binding ElementName=SyncronizedHeaderGrid}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Header 1" 
                            Binding="{Binding Item1}" />
        <DataGridTextColumn Header="Header 2" 
                            Binding="{Binding Item2}"/>
        <DataGridTextColumn Header="Header 3" 
                            Binding="{Binding Item3}"/>
    </DataGrid.Columns>
</DataGrid>

<DataGrid x:Name="SyncronizedHeaderGrid">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Header 1" 
                            Binding="{Binding Item1}" />
        <DataGridTextColumn Header="Header 2" 
                            Binding="{Binding Item2}"/>
        <DataGridTextColumn Header="Header 3" 
                            Binding="{Binding Item3}"/>
    </DataGrid.Columns>
</DataGrid>

Die Zweite Datagrids, Kopf- und Zellenbreite werden nun mit der ersten Gitter Kopfbreite synchronisiert.

fand ich eine Lösung für dieses Problem, und eine extra kühle Lösung :-) Sie können das WPF-Toolkit herunterladen und den Code des Datagrid erhalten. Sobald Sie den Code haben alles, was Sie tun müssen, ist die Datagrid Klasse ändern Framework statt DependencyObject zu erben. Sobald Sie dies tun - Sie sind mit nur einem Problem verlassen, würde die Datacontext der Säule nicht initialisiert werden, da die Spalte nicht Teil der logischen Struktur ist, um es zu der logischen Struktur hinzugefügt würde dies lösen. Sie können es tun, wie folgt: Wo die OnColumnInitialization ist:         private void OnColumnInitialization (object sender, EventArgs e)         {
            AddLogicalChild (Sender);         } Jetzt, wo es ist ein Teil der logischen Struktur Sie denselben Datenkontext haben, und Sie können auf die Bindung verwenden Width-Eigenschaft. Wenn alle auf die gleiche Breite gebunden sind - haben Sie eine komplette Synchronisierung der Breite der Spalten. Dieser arbeitete für mich :-) Gili

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top