Frage

Mit dem WPF Datagrid Ich habe die Notwendigkeit, verschiedene Display und die damit verbundene Eigenschaften eines Datagridcell zu ändern - wie der Vordergrund, Fontstyle, IsEnabled und so weiter - basierend auf dem jeweiligen Wert der Zellobjekteigenschaft.

Nun ist dies einfach in Code zu tun, zum Beispiel (eine beobachtbare Sammlung von ObservableDictionaries verwendet wird):

  var b = new Binding("IsLocked") { Source = row[column], Converter = new BoolToFontStyleConverter() };
  cell.SetBinding(Control.FontStyleProperty, b);

und funktioniert gut, aber ich kann nicht sehen, wie dies in XAML zu tun, da ich keine Möglichkeit zu Set finden Sie Pfad , um ein Eigenschaft des Zellobjekts.

Ein XAML Versuch ist:

<Setter Property="FontStyle">
    <Setter.Value>
        <MultiBinding Converter="{StaticResource IsLockedToFontStyleConverter}" Mode="OneWay" UpdateSourceTrigger="PropertyChanged">
              <Binding />
              <Binding RelativeSource="{x:Static RelativeSource.Self}"/>
        </MultiBinding>
    </Setter.Value>
</Setter>

, aber es wird keine Bindung an die IsLocked Eigenschaft

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
    var row = (RowViewModel) values[0];
    var cell = (DataGridCell) values[1];
    if (cell != null && row != null)
    {
        var column = DataGridMethods.GetColumn(cell);
        return row[column].IsLocked ? "Italic" : "Normal";
    }

    return DependencyProperty.UnsetValue;
}

Bitte beachten Sie, dass eine frühere Version zurück row [col] .IsLocked und stellen Sie den Fontstyle einen Datatrigger verwenden, aber ein zurückgegebenes Objekt Databound nicht.

Beachten Sie, natürlich, dass die Anwendung nicht weiß, was die Spalten zur Entwurfszeit.

Schließlich Datatable die sind viel zu ineffizient für meine Anforderungen, aber ich würde mich interessieren zu sehen, wie dies mit Tables sowieso erledigt ist, wenn es eine solche Lösung für sie ist, dies nützlich anderswo sein könnte (obwohl ich mit Sammlungen bevorzugen).

Sicher ist dies ein weit verbreitetes Problem, und ich bin ein WPF noobie alle MVVM auf meinem Projekt zu gehen versucht, aber dieses Problem ist mich wieder in Bezug halten, um die WPF Datagrid verwenden.

War es hilfreich?

Lösung

Nun, hier ist die einfachste Lösung, die ich gefunden habe. (Eigentlich hatte ich es, bevor ich diese und die andere Frage gestellt, aber mit einer solchen solution.Since embarrased nichts gehört haben, sonst hier und nur ist es für den Fall, jemand anderes mit dem gleichen Problem konfrontiert, ich dachte, ich würde es teilen.)

Setzen Sie einen Verweis auf das Zellobjekt in der Datagridcell-Tag-Eigenschaft. Ich tue dies mit einer Kombination von XAML und einem Code in einem Konverter verbindlich wie folgt:

   <Setter Property="Tag">
       <Setter.Value>
           <MultiBinding Converter="{StaticResource CellViewModelToTagConverter}" Mode="OneWay" UpdateSourceTrigger="PropertyChanged">
              <Binding />
              <Binding RelativeSource="{x:Static RelativeSource.Self}"/>
          </MultiBinding>
       </Setter.Value>
   </Setter>

und

 public class CellViewModelToTagConverter : IMultiValueConverter
 {
     public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
     {
        var row = values[0] as RowViewModel;
        var cell = values[1] as DataGridCell;
        if (row != null && cell != null)
        {
            var column = DataGridMethods.GetColumn(cell);
            // hack within hack!!! (using tag way is itself a hack?)
            var b = new Binding("Self") {Source = row[column]};
            cell.SetBinding(FrameworkElement.TagProperty, b);
            //...
            //return row[column];
            return DependencyProperty.UnsetValue;
        }
        return DependencyProperty.UnsetValue;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

Sie können sagen, was ich von dieser Lösung denken, durch meine Kommentare in den Konverter. (Ich hatte ein Selbst Eigenschaft auf dem Cell-Objekt hinzufügen und machen Selbst diese im Konstruktor =).

Still ermöglicht es mein Datagrid Codierung ganz MVVM sein - wenn Sie akzeptieren, dass das, was ich im Inneren des Wandlers im Einklang mit MVVM getan haben. Auf jeden Fall funktioniert es!

So ist es auf diese Weise tut, kann ich sehen, und verwalten alles von XAML wie Steuer solchen Bindung nur für bestimmte Spalten durch die XAML innerhalb der entsprechenden Spalte angewendete Cellstyles platzieren (die nicht diese über DataGrid.CellStyle tun).

Wie auch immer, ein Beispiel für die Nutzung ist

<Style.Triggers>
      <DataTrigger Value="true" Binding="{Binding RelativeSource={RelativeSource Self}, Path=Tag.IsLocked}">
            <Setter Property="FontStyle" Value="Italic"/>
            <Setter Property="IsEnabled" Value="False"/>
       </DataTrigger>
 </Style.Triggers>

Auf der XAML-Ebene ist es einfach und elegant IMHO (vor allem für verschiedene Quick-Infos und Popups für die ich beklemmend Verwendung von Zellobjekteigenschaften machen). Aber ich bin sicher, dass es ein besserer Weg, dies zu tun, oder?

Hoffentlich geht alles weg, wenn ich Net 4.0 und dynamische Objekte verwenden können, aber für dieses Projekt kann ich nicht.

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