Pergunta

Usando o WPF DataGrid, tenho a necessidade de alterar várias propriedades e propriedades relacionadas de um datagridCell - como primeiro plano, FontStyle, isenabled e assim por diante - com base no valor relevante da propriedade do objeto de célula.

Agora, isso é fácil de fazer no código, por exemplo (usando uma coleção observável de observação observada):

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

e funciona bem, no entanto, não consigo ver como fazer isso em xaml, pois não consigo encontrar como definir Caminho para a propriedade de um objeto celular.

Uma tentativa XAML é:

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

Mas não há ligação ao Está bloqueado propriedade

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

Observe que uma versão anterior retornou Linha [col]. e defina o FontStyle usando um datatrigger, mas um objeto retornado não é um banco de dados.

Observe, é claro, que o aplicativo não sabe quais são as colunas no momento do design.

Finalmente, os Datatable's são muito ineficientes para meus requisitos, mas eu estaria interessado em ver como isso é feito com o Datatables de qualquer maneira, se houver essa solução para eles, isso pode ser útil em outro lugar (embora eu prefira usar coleções).

Certamente esse é um problema comum e eu sou um WPF Noobie tentando ir a todo o MVVM no meu projeto, mas esse problema está me impedindo de usar o WPF DataGrid.

Foi útil?

Solução

Bem, aqui está a solução mais simples que encontrei. (Na verdade, eu tinha isso antes de postar isso e a outra pergunta, mas fiquei envergonhada em uma solução assim. Desde que não tenha ouvido mais nada aqui e apenas é, caso alguém mais se depare com o mesmo problema, pensei em compartilhá -lo.)

Coloque uma referência ao objeto de célula na propriedade DataGridCell Tag. Eu faço isso com uma combinação de XAML e uma ligação de código dentro de um conversor da seguinte forma:

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

e

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

Você pode dizer o que penso dessa solução pelos meus comentários dentro do conversor. (Eu tive que adicionar uma propriedade self ao objeto da célula e fazer eu = isso no construtor).

Ainda assim, permite que minha codificação Datagrid seja inteiramente MVVM - se você aceitar que o que eu fiz dentro do conversor é consistente com o MVVM. De qualquer forma, funciona!

Então, fazê -lo dessa maneira, eu posso ver e gerenciar tudo, desde o XAML, como controlar essa ligação apenas em determinadas colunas, colocando o XAML dentro da coluna relevante CellStyles (que não está fazendo isso via datagrid.CellStyle).

Enfim, um exemplo de uso é

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

No nível XAML, é simples e elegante (especialmente para várias dicas de ferramentas e pop -ups para os quais faço o uso pesado das propriedades do objeto celular). No entanto, tenho certeza de que há uma maneira melhor de fazer isso, existe?

Espero que tudo isso desapareça quando eu posso usar objetos Net 4.0 e dinâmico, mas para este projeto não posso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top