简体   繁体   中英

How to bind a MultiDataTrigger with bindings using different data contexts

I have a custom user control which is in the main window of my WPF application. Within the window is an ItemsControl. I have created a style so that I can bind to an array of items which is a property of my view-model class. The array holds indexes to the position of the items control. I should add that the custom control is inherits from Shape so it has the Stroke property.

public class ViewModel 
{
    ... 
    public List<int> Selections
    {
        get => _selections;
        set
        {
            if (value == _selections) return;
            _selections = value;
            OnPropertyChanged();
        }
    }
    public HypercombState State
    {
        get => _state;
        set
        {
            if (value == _state) return;
            _state = value;
            OnPropertyChanged();
        }
    }
}

Here is the converter that is responsible for identifying whether the view-model is holding selected indexes or not. If should return true if the item is selected during databinding.

public class ArrayContainsConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values[0] is not int id || values[1] is not List<int> array) return null;
        return array?.Contains(id);
    }
    ...
}


<Style.Triggers>
    <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
            <Condition Value="True">
                <Condition.Binding>
                    <MultiBinding Converter="{StaticResource ArrayContainsConverter}">
                        <Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="
                            {RelativeSource AncestorType=ContentPresenter}" />
                        <Binding Path="DataContext.Selections" />
                    </MultiBinding>
                </Condition.Binding>
            </Condition>
            ...
        </MultiDataTrigger.Conditions>
        <Setter Property="Stroke" Value="Chartreuse"></Setter>
    </MultiDataTrigger>
</Style.Triggers>

Whenever the Selections or State properties change, I would like to update the ItemsControl so that there is a Stroke as a visual cue for the item's selected state when true. I can see the Selections property changing if I use breakpoints but there the converter is not triggering when the list changes.

Try changing the datatype from List to ObservableCollection . There is a difference when using those 2 data types in WPF and usually I recommend using the latter for any trigger updates.

Also try updating the binding modes such as

<Binding Path="DataContext.Selections" />

To

<Binding Path="DataContext.Selections", Mode=“TwoWay” />

The difference between the two is that:

  1. List - Implements IList interface
  2. ObservableCollection - Implements INotifyCollectionChanged

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM