change itemscontrol checkbox foreground color based on textbox chacter length

harry777 61 Reputation points
2020-08-14T08:45:55.163+00:00

Hi,

In my WPF view I have one textbox and checkbox collection - binding in view model ObsevableCollection<MyClass> for itemscontrol.

I would like to change the colour and font size of the itemscontrol items based on the sum of lengths on checkbox content characters and textbox characters.

I want this to be triggered whenever user types in textbox.

if ((item.Count() + textBoxText.Count()) < 10)
    return Brushes.Black and normal font Size
else if ((item.Count() + textBoxText.Count()) > 10 && (item.Count() + textBoxText.Count()) < 20)
    return Brushes.Green and DemiBold fontsize 
else
    return Brushes.Red and DemiBold fontsize

Many thanks,
Harry

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,669 questions
0 comments No comments
{count} votes

3 additional answers

Sort by: Most helpful
  1. Peter Fleischer (former MVP) 19,231 Reputation points
    2020-08-16T07:09:57.037+00:00

    Hi,
    you can use Binding and MultiValueConverter. Try following demo:

    <Window x:Class="Window047"  
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
            xmlns:local="clr-namespace:WpfApp1.WpfApp047"  
            mc:Ignorable="d"  
            Title="Window047" Height="450" Width="800">  
      <Window.DataContext>  
        <local:ViewModel/>  
      </Window.DataContext>  
      <Window.Resources>  
        <local:TBConverter x:Key="conv"/>  
      </Window.Resources>  
      <StackPanel>  
        <TextBox Text="{Binding TbInfo, UpdateSourceTrigger=PropertyChanged}" Margin="5">  
          <TextBox.Foreground>  
            <MultiBinding Converter="{StaticResource conv}">  
              <Binding Path="TbInfo"/>  
              <Binding Path="Col"/>  
            </MultiBinding>  
          </TextBox.Foreground>  
          <TextBox.FontWeight>  
            <MultiBinding Converter="{StaticResource conv}">  
              <Binding Path="TbInfo"/>  
              <Binding Path="Col"/>  
            </MultiBinding>  
          </TextBox.FontWeight>  
        </TextBox>  
        <ComboBox ItemsSource="{Binding Col}" DisplayMemberPath="Info" Margin="5"/>  
      </StackPanel>  
    </Window>  
    

    17835-x.png

    0 comments No comments

  2. Peter Fleischer (former MVP) 19,231 Reputation points
    2020-08-16T13:10:13.407+00:00

    Hi,
    another approach is to use Style with Trigger:

    17858-x.png

    And ViewModel:

    Imports System.Collections.ObjectModel  
    Imports System.Globalization  
      
    Namespace WpfApp049  
      Public Class ViewModel  
        Public Property Col As New ObservableCollection(Of Data)(New Data() {New Data With {.Info = "data 1"},  
                                                                 New Data With {.Info = "data 2"},  
                                                                 New Data With {.Info = "data 3"}})  
        Public Property TbInfo As String  
      End Class  
      
      Public Class Data  
        Public Property Info As String  
      End Class  
      
      Public Class TBConverter  
        Implements IMultiValueConverter  
      
        Public Function Convert(values() As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IMultiValueConverter.Convert  
          If values IsNot Nothing AndAlso values.Length = 2 AndAlso values(0) IsNot Nothing Then  
            Dim tbInfo = values(0).ToString  
            Dim col = TryCast(values(1), Collection(Of Data))  
            If col IsNot Nothing Then  
              Dim lng = col.Count + tbInfo.Length  
              If lng >= 20 Then Return 20  
              If lng > 10 Then Return 10  
            End If  
          End If  
          Return 0  
        End Function  
      
        Public Function ConvertBack(value As Object, targetTypes() As Type, parameter As Object, culture As CultureInfo) As Object() Implements IMultiValueConverter.ConvertBack  
          Throw New NotImplementedException()  
        End Function  
      End Class  
      
    End Namespace  
    
    0 comments No comments

  3. harry777 61 Reputation points
    2020-08-18T20:34:56.927+00:00

    Hi Peter,

    Thanks a ton for comprehensive reply, much appreciated. However, I want to change the style (foreground and weight) of the checkbox content text in the itemscontrol and not the text box. Could you please hint me how to achieve that?

    <ItemsControl ItemsSource="{Binding MyClassCollection}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Columns="5"  VerticalAlignment="Top"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid Margin="5" HorizontalAlignment="Left">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                        <Rectangle Width="15" Height="15" Stroke="Black" Fill="{Binding ItemColor}" VerticalAlignment="Center"/>
                        <CheckBox Margin="2,0,0,0" Grid.Column="1" VerticalAlignment="Center" VerticalContentAlignment="Center"
                            Content="{Binding MyClass.Id}" 
                            IsChecked="{Binding ItemIsSelected, Mode=TwoWay}"
                            IsEnabled="{Binding ItemIsEnabled}">
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
    

    Many thanks,
    Harry

    0 comments No comments