Question

Thanks for all help in advance!

I have a listview that shows the user a List of ComboBoxes, in which he can choose different units. It looks similar to this:

<ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Name="ChangedIndicator"
                                   Text="#"
                                   Visibility="{Binding DefaultChanged, 
                                   Converter={StaticResource BoolToVis}}"/>
                        <TextBlock Text="{Binding Path=Name}"
                                   Margin="5"
                                   MinWidth="210"
                                   TextAlignment="Center"/>
                        <ComboBox  ItemsSource="{Binding Units}"
                                   DisplayMemberPath="Symbol" 
                                   SelectedValue="{Binding DefaultUnit.Key}" 
                                   SelectedValuePath="Key"
                                   Name="UserChangesComboBox">
                            <ComboBox.ItemTemplate>
                                <DataTemplate>
                                    <StackPanel Orientation="Horizontal">
                                        <TextBlock Text="{Binding Symbol}"/>
                                        <TextBlock Text=" ("/>
                                        <TextBlock Text="{Binding Key}"/>
                                        <TextBlock Text=")"/>
                                    </StackPanel>
                                </DataTemplate>
                            </ComboBox.ItemTemplate>
                        </ComboBox> 
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>

Now, my problem:

As you see, I want to show the user any changes done in the form of a '#' in a textbox next to the Combo. If the user has changed the selection of a certain combobox I want to show the '#'. I'm using the visibilityConverter for this, but thats not the problem.. Basically I want to have a property of Boolean or similar which is true for each combo when SelectionChanged is raised for each of the combos. Or maybe this idea goes into the wrong direction and someone of you can help me out with this..

I want something like this:

  (#)    Speed -> [m/s]
                  [km/h]

while the '#' indicates a user change in this combobox! And the [] is basically the combobox with it's two choices..

But the problem is that all comboboxes are objects in an ObservableCollection..

Thanks a lot for any help!

Was it helpful?

Solution 2

If you merely want to indicate the changed textbox, I would use a multibinding on the visibility property of the textbox. This works:

<ListView Name="LV_Items">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="#">
                        <TextBlock.Visibility>
                            <MultiBinding Converter="{StaticResource NonEqualValuesToVisibilityConverter}">
                                <Binding Path="ComboDefaultValue" Mode="OneWay"></Binding>
                                <Binding ElementName="CB_Selection" Path="SelectedValue" Mode="OneWay"></Binding>
                            </MultiBinding>
                        </TextBlock.Visibility>
                    </TextBlock>

                    <ComboBox Name="CB_Selection"  
                              ItemsSource="{Binding ComboItems}"
                              DisplayMemberPath="Item2" 
                              SelectedValue="{Binding ComboDefaultValue, Mode=OneTime}" 
                              SelectedValuePath="Item1">

                    </ComboBox>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

code for the multivalue converter:

public class NonEqualValuesToVisibilityConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (values == null || values.Length != 2)
        {
            return Visibility.Hidden;
        }

        return values[0].Equals(values[1]) ? Visibility.Hidden : Visibility.Visible;
    }

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

The listview is bound to collection of items like so:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        var items = new List<MyListViewItemData>();

        items.Add(new MyListViewItemData()
            {
                ComboDefaultValue = 1,
                ComboItems = new List<Tuple<int, string>>(){ new Tuple<int, string>(1, "m/s"), new Tuple<int, string>(2, "km/h") }
            });

        items.Add(new MyListViewItemData()
            {
                ComboDefaultValue = 10,
                ComboItems = new List<Tuple<int, string>>() { new Tuple<int, string>(10, "seconds"), new Tuple<int, string>(20, "minutes") }
            });

        LV_Items.ItemsSource = items;
    }
}

public class MyListViewItemData
{
    public List<Tuple<int, String>> ComboItems { get; set; }

    public int ComboDefaultValue { get; set; }
}

I chose an arbitrary class MyListViewItemData to store all possible values and the default value.

OTHER TIPS

I think the way you do is create DefaultChanged bool property in the same viewmodel which holds the combobox items collection also with SelectedItem property.

Whenever the selectedItem changes you will set that DefaultChanged to true and the '#' will appear in your view.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top