Change combo box item list depending on the Textbo

2019-03-03 16:59发布

问题:

I have two columns in my grid:

Name(Textbox) ---- ParentList(combobox).

A ----------------------- It should comprise of only B and C

B ----------------------- A and C

C ----------------------- A and B

My ParentList contains {A,B,C}.

How can I hide the particular item from the list depending on the text in the textbox?

XAML for my code is:

<Grid>
    <StackPanel >          
        <ListView>
            <ListView.View>  
                <GridView >
                    <GridViewColumn  Header="Name"  >
                        <GridViewColumn.CellTemplate >
                            <DataTemplate >
                                <WrapPanel >
                                    <TextBox x:Name="txName"  Text="{Binding Name}"  />                                      
                                </WrapPanel>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn  Header="Parent List"  >
                        <GridViewColumn.CellTemplate >
                            <DataTemplate >
                                <WrapPanel >
                                    <ComboBox x:Name="cbParentId" ItemsSource="{Binding Path=ParentList,ElementName=UI}"   />
                                </WrapPanel>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>
    </StackPanel>
</Grid>

回答1:

That's easy to achieve if you slightly adapt your data type class... I've had to guess at the type of your ParentList because you didn't show it:

private List<string> allItems = GetAllItems();

public ObservableCollection<string> ParentList
{
    get { return parentList; }
    set
    {
        parentList = value;
        NotifyPropertyChanged("ParentList");
    }
}

public string Name
{
    get { return name; }
    set
    {
        name = value;
        NotifyPropertyChanged("Name");
        ParentList = new ObservableCollection<string>(allItems.Where(i => IsFiltered(i)));
    }
}

private bool IsFiltered(string item)
{
    // implement your filter condition here
    return item.StartsWith("A");
}

So the basic idea is that you hold a private collection of all the possible values... this remains unchanged. Each time the Name property is changed, we create a new ParentList dependant on some filtering condition in the IsFiltered method.



回答2:

The simple and best solution [for me] would be to write a 'GotFocus' event and apply the Visibility on the required item.

    private void combobox_GotFocus_1(object sender, RoutedEventArgs e)
    {          
        var combobox = sender as ComboBox;

        if (combobox == null) return;
        var model = combobox.DataContext as Model;

        foreach (var item in combobox.ItemsSource)
        {
            if (item.Equals(model.Name))
            {
                var comboboxItem = combobox.ItemContainerGenerator.ContainerFromItem(item) as ComboBoxItem;
                if (comboboxItem != null)
                    comboboxItem.Visibility = Visibility.Collapsed;
            }
        }
    }


回答3:

You can make the ItemsSource as MultiBinding to be binded to the list and the textbox, and in the converter go over the list, and hide items you don't want (according to the textbox).

Not a too nice solution, but it should work.

This is the multibinding:

<MultiBinding Converter="{StaticResource myConverter}">
  <Binding ElementName="UI" Path="ParentList" />
  <Binding ElementName="txName" Path="Text" />
</MultiBinding>

And in the convert method run with foreach on the parnetlist, and conditions that if the ListItem equals the text, it should be collapsed.