5

Well, this may be an easy question but I am not able to find a solution for this.

I have a DataTrigger as

<DataTrigger Binding="{Binding Quantity}" Value="0">

Now I want to bind Value to a variable myVariable. So if the value of myVariable changes, the Value property of the DataTrigger changes too.

I have tried setting Binding but it I guess its not possible to set it. Is there any other method by which I can set this Value dynamically.

EDIT : I tried creating a data trigger of my own. But I am still not able to get things working.

This is the code :

DataTrigger d = new DataTrigger();
d.Binding = new Binding("Quantity");
d.Value = 1;
Setter s = new Setter(BackgroundProperty, Brushes.Red);
d.Setters.Add(s);

Style st = new Style(typeof(DataGridRow));
st.Triggers.Add(d);
this.Resources.Add(this.Resources.Count, st);

I want to use the above code in place of following xaml

<Page.Resources>
    <Style TargetType="DataGridRow">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Quantity}" Value="1">
                <Setter Property="Background" Value="Red" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Page.Resources>

Thanks.

Tanuj Wadhwa
  • 2,025
  • 9
  • 35
  • 57
  • `DataTrigger.Value` is not a dependency property, so this wouldn't work directly, you'll need some trick. – Vlad Jun 08 '13 at 15:26
  • I know but how? Is it possible to write a `DataTrigger` programatically? – Tanuj Wadhwa Jun 08 '13 at 15:29
  • See, for example, [this answer](http://stackoverflow.com/a/2244222/276994) featuring `MultiBinding` and converter. – Vlad Jun 08 '13 at 15:29
  • Check this if helps - http://stackoverflow.com/questions/6352085/wpf-calling-method-from-a-datatrigger – RockWorld Jun 08 '13 at 16:42
  • 1
    I had this exact problem before, I solved it by binding the Background colour to the object and using an IValueConverter that inspected the object and returned the appropriate colour. There are certainly better ways, but the clock was ticking and it was scalable enough to implement an entire rainbow of colours. – Gayot Fow Jun 09 '13 at 01:39
  • Does this answer your question? [Using binding for the Value property of DataTrigger condition](https://stackoverflow.com/questions/2240421/using-binding-for-the-value-property-of-datatrigger-condition) – StayOnTarget May 13 '22 at 19:46

1 Answers1

4

To my understanding of your problem, you are trying to find a way to set the Value of your DataTrigger according to the value of one of the properties of your view model. So here I have a solution.

Here is the View Model

public class ViewModel : INotifyPropertyChanged
{
    private string _text;
    private string _candidateValue;

    public string Text
    {
        get
        {
            return this._text;
        }
        set
        {
            this._text = value;
            if (null != PropertyChanged)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs("Text"));
            }
        }
    }

    public string CandidateValue
    {
        get
        {
            return this._candidateValue;
        }
        set
        {
            this._candidateValue = value;
            if (null != PropertyChanged)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs("Text"));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

And you need a IValueConverter in your binding of DataTrigger

public class ValueConverter : DependencyObject, IValueConverter
{

    public static readonly DependencyProperty CandidateValueProperty = DependencyProperty.Register("CandidateValue", typeof(string), typeof(ValueConverter));

    public string CandidateValue
    {
        get { return (string)GetValue(CandidateValueProperty); }
        set { SetValue(CandidateValueProperty, value); }
    }

    public ValueConverter()
        : base()
    { 
    }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (null != value)
        {
            if (value.ToString() == this.CandidateValue)
                return true;
        }
        return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }
}

And the xaml is quite simple

<TextBox x:Name="TextBox" Text="{Binding Text,UpdateSourceTrigger=PropertyChanged}">
    </TextBox>

You need to create your datatrigger in code behind.

public MainWindow()
    {
        InitializeComponent();

        //The view model object
        ViewModel vm = new ViewModel();
        vm.CandidateValue = "1";
        this.DataContext = vm;

        //create data trigger object for TextBox
        DataTrigger d = new DataTrigger();

        //create binding object for data trigger
        Binding b = new Binding("Text");

        ValueConverter c = new ValueConverter();
        b.Converter = c;
        //create binding object for ValueConverter.CandidateValueProperty
        Binding convertBinding = new Binding("CandidateValue");
        convertBinding.Source = vm;
        BindingOperations.SetBinding(c, ValueConverter.CandidateValueProperty, convertBinding);

        d.Binding = b;
        d.Value = true;

        Setter s = new Setter(TextBox.ForegroundProperty, Brushes.Red);
        d.Setters.Add(s);

        Style st = new Style(typeof(TextBox));
        st.Triggers.Add(d);
        this.TextBox.Style = st;
    }

The trick here is that the ValueConverter has a dependency property named CandidateValueProperty. And this property is bind to the CandidateValue of view model. So the foreground of the TextBox will be red when the input value equals to CandidateValue of view model.

Colin
  • 551
  • 2
  • 10