Pregunta

Uso de la cuadrícula de datos de WPF que tienen la necesidad de cambiar múltiples pantallas y propiedades relacionadas de una DataGridCell - como primer plano, FontStyle, IsEnabled y así sucesivamente - en base al valor correspondiente de la propiedad objeto de celda.

Ahora bien, esto es fácil de hacer en el código, por ejemplo (usando una colección observable de ObservableDictionaries):

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

y funciona bien, sin embargo no puedo ver cómo se hace esto en XAML ya no puedo encontrar ninguna manera de establecer ruta a la propiedad de un objeto de celda.

Uno intentos XAML es:

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

Pero no hay ninguna unión a los IsLocked propiedad

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

Tenga en cuenta que una versión anterior volvió fila [col] .IsLocked y ajuste el FontStyle utilizando un DataTrigger sino un objeto devuelto no es enlace de datos.

Tenga en cuenta, por supuesto, que la aplicación no sabe lo que son las columnas en tiempo de diseño.

Por último de DataTable son demasiado ineficientes para mis necesidades, pero yo estaría interesado en ver cómo se hace esto con tablas de datos de todos modos, si hay una solución para ellos, esto podría ser en otro lugar útil (aunque prefiero utilizando colecciones).

Sin duda, este es un problema común y yo soy un noobie WPF tratando de ir todo MVVM en mi proyecto, pero este tema me está frenando con respecto al uso de la cuadrícula de datos de WPF.

¿Fue útil?

Solución

Bueno, aquí está la solución más sencilla que he encontrado. (En realidad lo tenía antes he publicado esto y la otra pregunta, pero estaba avergonzado en una solution.Since tales haber oído nada más aquí y sólo lo es en cualquier otro caso, se enfrenta con el mismo problema, pensé que iba a compartirlo.)

Ponga una referencia al objeto de celda en la propiedad Tag DataGridCell. Lo hago con una combinación de XAML y un código de enlace dentro de un convertidor de la siguiente manera:

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

y

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

Se puede decir lo que pienso de esta solución por mis comentarios en el interior del convertidor. (He tenido que añadir un alojamiento con instalaciones al objeto de la célula y hacer self = esta en el constructor).

Todavía permite mi Datagrid de codificación para ser totalmente MVVM - si se acepta que lo que he hecho en el interior del convertidor es consistente con MVVM. De todos modos funciona!

Así que hacerlo de esta manera puedo ver y manejar todo, desde XAML tales como el control de la unión sólo en ciertas columnas colocando el XAML dentro de los CellStyles columnas correspondientes (que no está haciendo esto a través de DataGrid.CellStyle).

De todos modos, un ejemplo de uso es

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

En el nivel XAML es a la vez simple y elegante en mi humilde opinión (especialmente para diversos sobre herramientas y ventanas emergentes para que hago uso pesado de las propiedades de objeto de celda). Sin embargo, estoy seguro de que hay una mejor manera de hacer esto, ¿verdad?

Esperamos que todo esto desaparece cuando puedo usar Net 4.0 y dinámicos objetos, pero para este proyecto no puedo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top