1
  1. Entire row should be highlighted based on the user entered value in textbox.
  2. If the Place Name column of List View matches that value.

I've been able to achieve highlighting based on hard coded value in data trigger as below:

<DataTrigger Binding="{Binding Name}" Value="Manali"> <!-- this value should be dynamic based on element --> 
    <Setter Property="Background" Value="Yellow" />
 </DataTrigger>

Could you point me in right direction, Can I bind Value property of Data Trigger at runtime?

enter image description here

<Grid>
    <Grid.Row>1</Grid.Row>
    <Grid.Column>1</Grid.Column>
    <StackPanel VerticalAlignment="Stretch">

        <Label Content="Highlight word" />
        <TextBox
            x:Name="HighlightTextBox"
            Margin="0,0,0,20"
            Text="-TODO- Highlight Place Name column, based on entered value in this text box" />

        <ListView x:Name="AbListView" GridViewColumnHeader.Click="AbListView_OnClick">
            <ListView.Resources>
                <Style TargetType="{x:Type ListViewItem}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Name}" Value="Manali">
                            <Setter Property="Background" Value="Yellow" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ListView.Resources>
            <ListView.View>

                <GridView>
                    <GridViewColumn
                        Width="Auto"
                        DisplayMemberBinding="{Binding Path=Name}"
                        Header="Place Name" />

                    <GridViewColumn
                        Width="500"
                        DisplayMemberBinding="{Binding Path=State}"
                        Header="State" />

                </GridView>
            </ListView.View>
        </ListView>
        <Button
            x:Name="ApplyLabels"
            Margin="15,15,15,15"
            Click="ApplyLabels_OnClick">
            Apply Labels
        </Button>
    </StackPanel>
</Grid>

Code Behind:

public partial class MainWindow : Window
 {
    public ObservableCollection<TouristPlace> TouristPlacces =>
        new ObservableCollection<TouristPlace>(new List<TouristPlace>()
        {
            new TouristPlace("Manali", "KA", 51),
            new TouristPlace("Coorg", "KA", 10),
            new TouristPlace("Taj Mahal", "UP", 100),
            new TouristPlace("Jagannath Temple", "OR", 90),
        });

    public MainWindow()
    {
        InitializeComponent();
        AbListView.ItemsSource = TouristPlacces;
    }
}
Abhijeet
  • 13,562
  • 26
  • 94
  • 175
  • 1
    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) – Sinatr May 21 '21 at 12:56

1 Answers1

3

Can I bind Value property of Data Trigger at runtime?

Short answer: No, you can't.

But The view or view model could (and should) handle the highlighting. Given your current implementation, you could handle the TextChanged event for the TextBox like this:

private void HighlightTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    if (IsLoaded)
    {
        string text = HighlightTextBox.Text;
        foreach (var place in AbListView.Items.OfType<TouristPlace>())
            place.IsHighlighted = place.Name == text;
    }
}

The TouristPlace should have an IsHighlighted property and implement the INotifyPropertyChanged interface:

public class TouristPlace : INotifyPropertyChanged
{
    public TouristPlace(string name, string state, int id)
    {
        Name = name;
        State = state;
        Id = id;
    }

    public string Name { get; }
    public string State { get; }
    public int Id { get; }

    private bool _isHighlighted;
    public bool IsHighlighted
    {
        get { return _isHighlighted; }
        set { _isHighlighted = value; NotifyPropertyChanged(); }
    }

    public event PropertyChangedEventHandler PropertyChanged; 
    private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

XAML:

<TextBox
    x:Name="HighlightTextBox"
    Margin="0,0,0,20"
    Text="-TODO- Highlight Place Name column, based on entered value in this text box"
    TextChanged="HighlightTextBox_TextChanged"/>

<ListView x:Name="AbListView" ItemsSource="{Binding TouristPlacces}" GridViewColumnHeader.Click="AbListView_OnClick">
    <ListView.Resources>
        <Style TargetType="{x:Type ListViewItem}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsHighlighted}" Value="True">
                    <Setter Property="Background" Value="Yellow" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ListView.Resources>
    <ListView.View>

        <GridView>
            <GridViewColumn
                        Width="Auto"
                        DisplayMemberBinding="{Binding Path=Name}"
                        Header="Place Name" />

            <GridViewColumn
                        Width="500"
                        DisplayMemberBinding="{Binding Path=State}"
                        Header="State" />

        </GridView>
    </ListView.View>
</ListView>

enter image description here

mm8
  • 163,881
  • 10
  • 57
  • 88
  • Sounds more exciting compared to Multi Data Trigger. Let me try and come back. Thanks again. +1 – Abhijeet May 21 '21 at 16:15
  • 1
    thanks. You have not only given elegant solution to the question, but also have improvised my approach for always, to approach it correctly. So proud to have been connected to you.. :-) – Abhijeet May 22 '21 at 09:33