Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding in WPF DataTrigger value

Tags:

c#

.net

wpf

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.

like image 314
Tanuj Wadhwa Avatar asked Oct 04 '22 21:10

Tanuj Wadhwa


1 Answers

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.

like image 106
Colin Avatar answered Oct 07 '22 17:10

Colin