2017-01-18 5 views
1

У меня есть ListView, которые содержат 2 TextBlocks в виде списка Пунктполучение TextBlock из представления списка динамически

Я хочу покрасить TextBlocks динамически

, как я могу получить сделать TextBlock? оценят пример.

Спасибо вам за вашу поддержку

креплени Мой XAML:

<ListView x:Name="LV" ItemsSource= "{Binding Lggv}" SelectionChanged="dataGridData_SelectionChanged" ItemContainerStyle="{StaticResource ListViewItemStyle}" > 
       <ListView.ItemTemplate> 
        <DataTemplate> 
         <StackPanel > 
          <Border BorderThickness="1" BorderBrush="Black"> 

           <Grid> 
            <Grid.ColumnDefinitions> 
             <ColumnDefinition Width="150"></ColumnDefinition> 
             <ColumnDefinition Width="50"></ColumnDefinition> 
             <ColumnDefinition Width="1*"></ColumnDefinition> 
            </Grid.ColumnDefinitions> 
            <TextBlock x:Name="tbHeader" Text="{Binding Info }" AllowDrop="True" FontWeight="Bold" Grid.Column="2" > 
            <TextBlock.Background> 
             <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">            
              <GradientStop Color="#FFCEE6C6" Offset="0.008"/> 
              <GradientStop Color="#FF9ECF8C" Offset="0.987"/> 
             </LinearGradientBrush> 
            </TextBlock.Background> 

           </TextBlock> 
           </Grid> 
          </Border> 
          <Grid x:Name="GridData" > 
           <Grid.Background> 
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 
             <GradientStop Color="#FFC5DDFF" Offset="0"/> 
             <GradientStop Color="#FFA8C8F7" Offset="1"/> 
            </LinearGradientBrush> 
           </Grid.Background> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition Width="150"></ColumnDefinition> 
            <ColumnDefinition Width="50"></ColumnDefinition> 
            <ColumnDefinition Width="1*"></ColumnDefinition> 
           </Grid.ColumnDefinitions> 
           <Border Grid.Column="0" BorderThickness="2" BorderBrush="Black"> 
            <TextBlock Text="{Binding DateTime}" ></TextBlock> 
           </Border> 
           <Border Grid.Column="1" BorderThickness="2" BorderBrush="Black"> 
            <TextBlock Text="{Binding ComPort}"></TextBlock> 
           </Border> 
           <Border Grid.Column="2" BorderThickness="2" BorderBrush="Black"> 
            <TextBlock Text="{Binding Data}" ></TextBlock> 
           </Border> 
          </Grid> 
         </StackPanel> 
        </DataTemplate>  
       </ListView.ItemTemplate>         

      </ListView> 
+0

Я бы использовал ValueConverter, чтобы изменить значение привязки к кисти, тогда привязка сделает это для вас – MikeT

ответ

1

Лучший способ сделать это с IValueConverter

как это позволяет вам держать ваш взгляд и ViewModel Seperate, хотя, если вы не заботитесь о том, что @sasanaf ответ является правильным perfertly

здесь является примером простой основе кисти преобразователя

public class PriorityConverter : IValueConverter 
{ 
    public Brush HighBrush { get; set; } 
    public Brush LowBrush { get; set; } 
    public Brush MediumBrush { get; set; } 
    public Brush DefaultBrush { get; set; } 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     var priority = value as Priority?; 
     if (priority.HasValue) 
     { 
      switch (priority.Value) 
      { 
       case Priority.High: 
        return HighBrush; 
       case Priority.Medium: 
        return MediumBrush; 
       case Priority.Low: 
        return LowBrush; 
       default: 
        return DefaultBrush; 
      } 
     } 
     else 
      throw new InvalidCastException($"{value} is not a Priority"); 
    } 

Вы бы затем добавить конвертер в качестве ресурса для вашего приложения,

<local:PriorityConverter x:Key="PriorityConverter" > 
    <local:PriorityConverter.DefaultBrush> 
     <SolidColorBrush Color="{DynamicResource {x:Static SystemColors.ControlColorKey}}"/> 
    </local:PriorityConverter.DefaultBrush> 
    <local:PriorityConverter.HighBrush> 
     <LinearGradientBrush> 
      <GradientStop Color="Red" Offset="0.5"/> 
      <GradientStop Color="Yellow" /> 
     </LinearGradientBrush> 
    </local:PriorityConverter.HighBrush> 
    <local:PriorityConverter.MediumBrush> 
     <SolidColorBrush Color="Blue"/> 
    </local:PriorityConverter.MediumBrush> 
    <local:PriorityConverter.LowBrush> 
     <SolidColorBrush Color="Green"/> 
    </local:PriorityConverter.LowBrush> 
</local:PriorityConverter> 

и, наконец, использовать его на своем связывании

<TextBlock Background="{Binding Priority, Converter={StaticResource PriorityConverter}}" /> 
+0

Хороший подход 1 для этого. – Rudra

0

Если у вас возникли MVVM подход, я бы установить цвета в ViewModel и связывают их со свойствами.

Edit: TextBlock, как это:

       <TextBlock DataContext="ViewModel" 
             Background="{Binding SpecificColor}"> 
           </TextBlock> 

И в ViewModel, позволяющие задать при инициализации или в любом конкретном цвете которым событие, которое вы хотели бы. Для примера:

private Brush m_SpecificColor; 
    public Brush SpecificColor 
    { 
     get { return m_SpecificColor; } 
     set 
     { 
      m_SpecificColor = value; 
      OnPropertyChanged("SpecificColor"); 
     } 
    } 
    private void SetColor() 
    { 
     SpecificColor = (Brush)new BrushConverter().ConvertFromString("Green"); 
    } 
+0

Кисти - это элементы вида, имеющие их в View Model, это не очень хорошая идея – MikeT

+0

Ну вы можете мне сказать где недостаток такого подхода? Альтернативой будет IValueConverter для цветов, например, в зависимости от данных, которые у вас есть, цвета, который вы получаете. – sasanaf

+0

Не думал об этом, спасибо – sasanaf

0

Я думаю, что вы хотите изменить цвет динамически на основе какого-либо свойства объекта (класс с «Info», «DateTime», «СОМ порт» и «данные» свойства) в ваша коллекция источников Lggv.

Вы можете использовать стиль с DataTrigger, который привязывается к свойству этого класса, то есть к типу T (опять же это тот, который содержит данные «Info», «DateTime», «ComPort» и «Data», свойства) в исходной коллекции IEnumerable<T> (Lggv), что вы связывающиеся с:

<TextBlock x:Name="tbHeader" Text="{Binding Info}" AllowDrop="True" FontWeight="Bold" Grid.Column="2"> 
    <TextBlock.Style> 
     <Style TargetType="TextBlock"> 
      <Setter Property="Background"> 
       <Setter.Value> 
        <!-- this is the default background--> 
        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 
         <GradientStop Color="#FFCEE6C6" Offset="0.008"/> 
         <GradientStop Color="#FF9ECF8C" Offset="0.987"/> 
        </LinearGradientBrush> 
       </Setter.Value> 
      </Setter> 
      <Style.Triggers> 
       <!-- This trigger changes the background to green when the "Info" property of your data object returns "Some info..." --> 
       <DataTrigger Binding="{Binding Info}" Value="Some info..."> 
        <Setter Property="Background"> 
         <Setter.Value> 
          <SolidColorBrush>Green</SolidColorBrush> 
         </Setter.Value> 
        </Setter> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </TextBlock.Style> 
</TextBlock> 
0

вы можете использовать IValueConverter преобразовать объект в цвет фона. Ниже приведен пример.

class BackgroundColorConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     LinearGradientBrush myLinearGradientBrush = new LinearGradientBrush(); 
     if (value != null) 
     { 
      string strValue = value.ToString(); 


      myLinearGradientBrush.StartPoint = new System.Windows.Point(0, 0); 
      myLinearGradientBrush.EndPoint = new System.Windows.Point(1, 1); 

      switch (strValue) 
      { 
       case "Match1": 
        myLinearGradientBrush.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0)); 
        myLinearGradientBrush.GradientStops.Add(new GradientStop(Colors.Red, 0.25)); 
        break; 
       case "Match2": 
        myLinearGradientBrush.GradientStops.Add(new GradientStop(Colors.Blue , 0.0)); 
        myLinearGradientBrush.GradientStops.Add(new GradientStop(Colors.BlueViolet, 0.25)); 
        break; 
       default: 
        myLinearGradientBrush.GradientStops.Add(new GradientStop(Colors.Green , 0.0)); 
        myLinearGradientBrush.GradientStops.Add(new GradientStop(Colors.GreenYellow, 0.25)); 
        break; 
      } 
     } 
     return myLinearGradientBrush; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Объявить преобразование ценности в ресурсе, как показано ниже.

<Window.Resources> 
    <local:BackgroundColorConverter x:Key="BackgroundColorConverter"/> 
</Window.Resources> 

Ниже приведен кодер Xaml.

<TextBlock x:Name="tbHeader" Text="{Binding Info }" Background="{Binding Path=property, Converter={StaticResource BackgroundColorConverter}}" AllowDrop="True" FontWeight="Bold" Grid.Column="2"/> 

другой подход если вы хотите использовать ресурс. Вы можете определить цвет в окнах или ресурс управления пользователями. После этого вам придется использовать IMultiValueConverter. Передайте вам свойство и окна или пользовательский элемент управления MultiValueConverter. Вам нужно использовать относительный источник, чтобы получить привязку окон или пользовательского контроля. Затем вы можете вернуть ресурс в соответствии с условием соответствия.

+0

, вам не нужно использовать IMultiValueConverter для использования ресурсов, просто установите их как свойства – MikeT

+0

В соответствии с вопросом, Если он хочет использовать LinearGradientBrush из ресурса, он будет иметь несколько ресурсов и должен установить его с помощью свойства в соответствии со значением свойства. Таким образом, если есть один ресурс, который вы хотите, вы можете указать пользователю свойство, иначе вам понадобится многозначный конвертер, чтобы получить правильный ресурс по значению. – Rudra

0

Лично я хотел бы сделать это с DataTrigger:

<Style x:Key="TextBlockStyle" TargetType="TextBlock"> 
    <Setter Property="Background"> 
     <Setter.Value> 
      <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 
       <GradientStop Color="#FFCEE6C6" Offset="0.008"/> 
       <GradientStop Color="#FF9ECF8C" Offset="0.987"/> 
      </LinearGradientBrush> 
     </Setter.Value> 
    </Setter> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding YourProperty}" Value="YourPropertyValue"> 
      <Setter Property="Background"> 
       <Setter.Value> 
        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 
         <GradientStop Color="Red" Offset="0.008"/> 
         <GradientStop Color="Orange" Offset="0.987"/> 
        </LinearGradientBrush> 
       </Setter.Value> 
      </Setter> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

Вы не то должны иметь класс, определенный делать то, что относительно простая задача.

Смежные вопросы