2012-06-10 2 views
2

Я пытаюсь установить другой цвет для нечетных строк с помощью XAML.Как проверить, имеет ли строка нечетное число?

В этом документе есть 3 разных типа данных, которые я хочу по-разному покрасить, и простое изменение AlternatingRowBackground не будет выполнено.

Я планирую использовать что-то вроде

<MultiDataTrigger> 
    <MultiDataTrigger.Conditions> 
     <Condition Binding="{Binding Type}" Value="0"/>       
     <Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="False"/> 
     <Condition Binding="{Binding IsOddRow, RelativeSource={RelativeSource Self}}" Value="False"/> 
    </MultiDataTrigger.Conditions>  
    <Setter Property="Background" Value="#FFDFE6ED"/>     
</MultiDataTrigger> 

Там, кажется, не быть таким свойством, как IsOddRow. Какую собственность я должен проверить вместо этого?

ответ

2

Я не уверен, какой тип сетки/строки вы используете, поэтому я не могу дать вам точные имена свойств, однако, привязать к индексу строки (номер строки) и использовать value converter (который возвращает true) на проверьте, является ли строка нечетной или четной.

3

Вы можете установить AlternationCount на DataGrid, а затем привязать к предку DataGridRows приложенное имущество ItemsControl.AlternationIndex. Если значение равно «1», у вас есть номер нечетной строки.

<DataGrid ItemsSource="{Binding ...}" 
      AlternationCount="2"> 
    <DataGrid.CellStyle> 
     <Style TargetType="DataGridCell"> 
      <Style.Triggers> 
       <MultiDataTrigger> 
        <MultiDataTrigger.Conditions> 
         <Condition Binding="{Binding Type}" Value="0"/> 
         <Condition Binding="{Binding RelativeSource={RelativeSource Self}, 
                Path=IsSelected}" 
            Value="False"/> 
         <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}, 
                Path=(ItemsControl.AlternationIndex)}" 
            Value="1"/> 
        </MultiDataTrigger.Conditions> 
        <Setter Property="Background" Value="#FFDFE6ED"/> 
       </MultiDataTrigger> 
       <!-- ... --> 
      </Style.Triggers> 
     </Style> 
    </DataGrid.CellStyle> 
    <!-- ... --> 
</DataGrid> 

Обратите внимание, что при привязке к вложенным собственности, вы должны поставить скобки вокруг вложенного свойства. Path=(ItemsControl.AlternationIndex) будет работать, но Path=ItemsControl.AlternationIndex не будет.


Update
Вы также можете создать свойство IsOddRow через прикрепленным поведения. В поведении вы подписываетесь на LoadingRow. В обработчике событий вы получаете индекс для загруженной строки и проверяете, является ли это нечетным или нет. Затем результат сохраняется в прикрепленном объекте под названием IsOddRow, с которым вы можете привязываться.

Чтобы начать поведение добавить behaviors:DataGridBehavior.ObserveOddRow="True" к DataGrid

<DataGrid ItemsSource="{Binding ...}" 
      behaviors:DataGridBehavior.ObserveOddRow="True"> 
    <DataGrid.RowStyle> 
     <Style TargetType="DataGridRow"> 
      <Style.Triggers> 
       <MultiDataTrigger> 
        <MultiDataTrigger.Conditions> 
         <Condition Binding="{Binding Type}" Value="0"/> 
         <Condition Binding="{Binding Path=IsSelected, 
                RelativeSource={RelativeSource Self}}" Value="False"/> 
         <Condition Binding="{Binding Path=(behaviors:DataGridBehavior.IsOddRow), 
                RelativeSource={RelativeSource Self}}" Value="False"/> 
        </MultiDataTrigger.Conditions> 
        <Setter Property="Background" Value="#FFDFE6ED"/> 
       </MultiDataTrigger> 
      </Style.Triggers> 
     </Style> 
    </DataGrid.RowStyle> 
</DataGrid> 

DataGridBehavior

public class DataGridBehavior 
{ 
    #region ObserveOddRow 

    public static readonly DependencyProperty ObserveOddRowProperty = 
     DependencyProperty.RegisterAttached("ObserveOddRow", 
              typeof(bool), 
              typeof(DataGridBehavior), 
              new UIPropertyMetadata(false, OnObserveOddRowChanged)); 
    [AttachedPropertyBrowsableForType(typeof(DataGrid))] 
    public static bool GetObserveOddRow(DataGrid dataGrid) 
    { 
     return (bool)dataGrid.GetValue(ObserveOddRowProperty); 
    } 
    public static void SetObserveOddRow(DataGrid dataGrid, bool value) 
    { 
     dataGrid.SetValue(ObserveOddRowProperty, value); 
    } 

    private static void OnObserveOddRowChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) 
    { 
     DataGrid dataGrid = target as DataGrid; 
     dataGrid.LoadingRow += (object sender, DataGridRowEventArgs e2) => 
     { 
      DataGridRow dataGridRow = e2.Row; 
      bool isOddRow = dataGridRow.GetIndex() % 2 != 0; 
      SetIsOddRow(dataGridRow, isOddRow); 
     }; 
    } 

    #endregion // ObserveOddRow 

    #region IsOddRow 

    public static DependencyProperty IsOddRowProperty = 
     DependencyProperty.RegisterAttached("IsOddRow", 
              typeof(bool), 
              typeof(DataGridBehavior), 
              new PropertyMetadata(false)); 
    [AttachedPropertyBrowsableForType(typeof(DataGridRow))] 
    public static bool GetIsOddRow(DataGridRow dataGridCell) 
    { 
     return (bool)dataGridCell.GetValue(IsOddRowProperty); 
    } 
    public static void SetIsOddRow(DataGridRow dataGridCell, bool value) 
    { 
     dataGridCell.SetValue(IsOddRowProperty, value); 
    } 

    #endregion // IsOddRow 
} 
+0

Если элемент управления является стандартным DataGrid, то это лучший подход, чем мой (нет необходимости в преобразователе значений). –

0

использования AlternationCount="2" на Почти каждый ответ, но я нахожу это немного слишком ограничивающими. На моей стороне я использую что-то вроде AlternationCount="{ Binding MainData.ProjColl.Count}", чтобы пронумеровать мои строки до конца (позаботьтесь, чтобы он начинался с 0!).

В этом случае мне нужен конвертер значений, упомянутый @Danny Varod.

Я использую конвертер чередовать цвет строк (почти отвечая на вопрос)

public class IsEvenConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, 
     object parameter, CultureInfo culture) 
    { 
     bool res = false; 
     int? val = value as int?; 
     if (null != val) 
      res = (0 == (val % 2)); 
     return res; 
    }  
    ... 
} 

И вызывающий XAML

<UserControl ... 
<UserControl.Resources> 
    ... 
    <vm_nmspc:IsEvenConverter x:Key="IsEven"/> 
    <Style TargetType="DataGridRow"> 
     <Setter Property="Width" Value="Auto"/> 
     <Setter Property="Background" Value="LightGray"/> 

     <!--Converter will be used below--> 

     <Style.Triggers> 
      ... 
      <Setter Property="Background" Value="LightGray"/ 
      <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, 
              Path=(ItemsControl.AlternationIndex), 
              Converter={StaticResource ResourceKey=IsEven}}" Value="true"> 
       <Setter Property="Background" Value="Lavender"/> 
      </DataTrigger> 
      <Trigger Property="IsMouseOver" Value="True" > 
       <Setter Property="Background" Value="LightGreen"/> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 
</UserControl.Resources> 

<Grid> 
    <DataGrid ItemsSource="{Binding MainData.ProjColl}" AutoGenerateColumns="False" 
    AlternationCount="{ Binding MainData.ProjColl.Count}" > 
    ... 
    <DataGridTextColumn Header="Project Name" .... 

    </DataGrid> 
</Grid> 
</UserControl> 

и некоторые дискретные скриншоты

enter image description here enter image description here

Другая часть того же кода: Simple way to display row numbers on WPF DataGrid