2
votes

I have an editor view that can be used for multiple edited objects. The view model for multiple objects provides a property like Field1Multiple of type bool for each field that needs to be handled. In this case, it's only ComboBox controls for now. Whenever multiple differing values shall be indicated for that field, a certain style should be applied to that control which is defined in App.xaml. That style changes the background of the control to visualise that there is no single value that can be displayed here.

I've tried with this XAML code:

<ComboBox
  ItemsSource="{Binding Project.Field1Values}" DisplayMemberPath="DisplayName"
  SelectedItem="{Binding Field1}">
  <ComboBox.Style>
    <Style>
      <Style.Triggers>
        <DataTrigger Binding="{Binding Field1Multiple}" Value="true">
          <Setter
            Property="ComboBox.Style"
            Value="{StaticResource MultiValueCombo}"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </ComboBox.Style>
</ComboBox>

But it doesn't work because I cannot set the Style property from inside a Style. If I use triggers directly on the control, there may only be EventTriggers, no DataTriggers, the compiler says.

How can I set the control's style based on a binding value? Or, how can I set a certain style for a control if a binding value is true?

1
Do you need to change only the background of the combobox? - michele
How complex is your Style? Typically I just add the setters that change to the trigger, which can include the ItemTemplate - Rachel
Check this stackoverflow.com/questions/3397497/… He did something similar - ígor
Thing is, that style will be used for every single field with multiple editing support, and it's gonna be hundreds of times... I wouldn't want to copy even a single line of style so often. - ygoe

1 Answers

5
votes

(EDIT to full solution)

You can use converter:

  public class AnyIsMultipleToStyle : IValueConverter
    {
        public Style NormalStyle { get; set; }

        public Style MultiStyle { get; set; }


        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value != null)
            {
                IList<SampleClass> list= value as IList<SampleClass>;
                if (list!=null)
                {
                    if (list.Any(i => i.Multi))
                        return MultiStyle;

                }

            }
            return NormalStyle;
        }

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

And in your xaml:(You indicate normal style and multistyle to converter)

 <Window.Resources>

        <Style x:Key="MultiValueCombo"  TargetType="{x:Type ComboBox}">

            <Setter Property="Background" Value="Olive" />
        </Style>

        <Style x:Key="NormalCombo"  TargetType="{x:Type ComboBox}">
            <Setter Property="Background" Value="Red" />
        </Style>
        <my:AnyIsMultipleToStyle x:Key="AnyIsMultipleToStyle1" MultiStyle="{StaticResource MultiValueCombo}" NormalStyle="{StaticResource NormalCombo }"  />





    </Window.Resources>
    <Grid>

        <ComboBox    ItemsSource="{Binding Items, ElementName=root}"  >
            <ComboBox.Style>
                <Binding Converter="{StaticResource AnyIsMultipleToStyle1}" Path="Items" ElementName="root" >

                    </Binding>
            </ComboBox.Style>

        </ComboBox>
    </Grid>