Question

Utilisation du DataGrid WPF J'ai la nécessité de modifier divers affichage et propriétés connexes d'un DataGridCell - comme Premier plan, FontStyle, IsEnabled et ainsi de suite - en fonction de la valeur pertinente de la propriété d'objet cellulaire.

Maintenant, c'est facile à faire dans le code, par exemple (en utilisant une collection de Observable ObservableDictionaries):

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

et fonctionne très bien, mais je ne vois pas comment faire cela en XAML puisque je ne trouve aucun moyen de définir Chemin à la propriété d'un objet cellulaire.

Une tentative XAML est:

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

mais il lie pas à la IsLocked propriété

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;
}

S'il vous plaît noter que la version précédente retour row [col] .IsLocked et réglez la FontStyle en utilisant un DataTrigger mais un objet retourné n'est pas lié aux données.

Note, bien sûr, que l'application ne sait pas ce que les colonnes sont au moment de la conception.

Enfin de DataTable sont beaucoup trop inefficace pour mes besoins mais je serais curieux de voir comment cela se fait avec DataTables de toute façon, s'il y a une telle solution pour eux, cela pourrait être utile ailleurs (même si je préfère utiliser des collections).

Certes, cela est un problème commun et je suis un noobie WPF essayant d'aller MVVM sur mon projet, mais cette question me tient en retrait par rapport à l'utilisation du DataGrid WPF.

Était-ce utile?

La solution

Eh bien est la solution la plus simple ici, je l'ai trouvé. (En fait, je l'avais avant posté et l'autre question, mais a été embarrassés par au solution.Since d'un tel avoir entendu rien d'autre ici et qu'il est tout simplement au cas où quelqu'un d'autre est confronté au même problème, je pensais que je le partagerais.)

Mettre une référence à l'objet de cellule dans la DataGridCell propriété Tag. Je le fais avec une combinaison de XAML et d'un code de liaison à l'intérieur d'un convertisseur comme suit:

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

et

 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();
    }
}

Vous pouvez dire ce que je pense de cette solution par mes commentaires à l'intérieur du convertisseur. (Je devais ajouter une propriété d'auto à l'objet cellulaire et faire Self = ce dans le constructeur).

Néanmoins, il permet mon codage Datagrid être entièrement MVVM - si vous acceptez que ce que je l'ai fait à l'intérieur du convertisseur est compatible avec MVVM. Quoi qu'il en soit, il fonctionne!

Il fait donc de cette façon que je peux voir et tout gérer à partir XAML tels que le contrôle sur une telle liaison que certaines colonnes en plaçant le XAML dans les cellstyles de colonne pertinents (qui ne le fait pas par DataGrid.CellStyle).

Quoi qu'il en soit, un exemple d'utilisation est

<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>

Au niveau XAML, il est à la fois simple et élégante à mon humble avis (en particulier pour les différentes info-bulles et les popups pour lesquels je fais une utilisation intensive des propriétés de l'objet cellulaire). Cependant, je suis sûr qu'il ya une meilleure façon de le faire, est-il?

Espérons que tout cela disparaît quand je peux utiliser des objets Net 4.0 et dynamique, mais pour ce projet, je ne peux pas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top