如何在每个ListItem的第二个组合框中显示子选择?

时间:2014-12-24 19:26:26

标签: c# wpf data-binding combobox

在我的应用程序中,我有可以包含Town的项目。每个TownPostalCodeName组成,例如

<Code>
  <Row
    Code="1234"
    Name="County A - Town A"
  />
</Code>
<Code>
  <Row
    Code="1234"
    Name="County A - Town B"
  />
</Code>
<Code>
  <Row
    Code="1235"
    Name="County B"
  />
</Code>
<Code>
  <Row
    Code="1236"
    Name="County C"
  />
</Code>

几个城镇可以重复PostalCode

在我的UI中,我显示如下选择: enter image description here

但这对用户来说很困惑,因为有多个类似的PostalCode

有没有办法按每个不同的TownPostalCode进行分组,然后使用已过滤的ComboBox过滤第二个Name

一个重要的评论是,TownItem的属性,属于ListView ItemsSource

修改

我已根据建议更改了我的代码:

XAML

    <ComboBox x:Name="PostalCodeComboBox"
        ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListView}}, Path=DataContext.DistinctPostalCodeTowns}"
        SelectedItem="{Binding Address.Town}" SelectionChanged="PostalCodeComboBox_SelectionChanged" />

    <ComboBox x:Name="NameComboBox"
        ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListView}}, Path=DataContext.TownsByCode}"
        SelectedItem="{Binding Address.Town}" SelectionChanged="NameComboBox_SelectionChanged" />

视图模型

    public MainWindowViewModel()
    {
        VivendaContext = new DataModels.VivendaContext();
        //Call a ToList to load the data into the .Local property.
        VivendaContext.Premises.ToList();
        Premises = VivendaContext.Premises.Local;
        Towns = VivendaContext.Towns.ToList();
        //http://stackoverflow.com/a/1300116/1653998
        DistinctPostalCodeTowns = VivendaContext.Towns.DistinctBy(t => t.PostalCode).ToList();
        TownsByCode = Towns;
    }

    internal void PostalCodeComboBox_SelectionChanged(ComboBox sender)
    {
        if(sender.SelectedItem as Town != null)
        {
            TownsByCode = Towns.Where(t => t.PostalCode == (sender.SelectedItem as Town).PostalCode).ToList();
        } else
        {
            TownsByCode = Towns;
        }
    }

当我选择PostalCode时,这非常有用,它会使用该邮政编码过滤城镇。但是当我加载我的数据(或通过其Town选择Name)时,我只能看到PostalCode当它是第一个带有该邮政编码的城镇时

我知道这是DistinctBy的副作用,而且Town属性中并非所有DistinctPostalCodeTowns实体都可用。

我的第一个想法是在我的SelectionChanged上使用NameComboBox事件,通过其邮政编码选择正确的Town,但每个项目都会重复PostalCodeComboBox ,我无法访问它。

有关如何让PostalCodeComboBox选择正确PostalCode的任何建议吗?

2 个答案:

答案 0 :(得分:1)

您必须定义两个集合。第一个将包含不同的代码,第二个将通过代码为代码列表框中的每个SelectionChanged事件动态填充Towns。

public string CurrentCode {get;set;}
public List<string> AllCodes {get;set;}
public List<Town> TownsByCode {get {return AllTowns.Where(r=>Code == CurrentCode).ToList();}}
public List<Town> AllTowns {get;set;}

XAML

// Codes selector
<ListBox SelectedItem="{Binding CurrentCode, Mode=TwoWay}" ItemsSource="Binding AllCodes">
</ListBox>

// Towns by code
<ListBox ItemsSource="Binding TownsByCode" />

同样在CurrentCode setter中,您必须通知TownsByCode属性已更改。

答案 1 :(得分:0)

首先,如果要在XAML中定义名称,则应通过以下方式定义:

<ComboBox Name="combo" HorizontalAlignment="Left" Margin="319,78,0,0" VerticalAlignment="Top" Width="120"/>

您可以通过这种方式在C#代码中编辑它:

combo.Items.Add("Hello");
combo.Items.Add("Combo");
combo.Items.Add("Box");

但是如果你想用C#编写整个代码:

ComboBox combo2 = new ComboBox();
combo2.Items.Add("I`m");
combo2.Items.Add("Mohamed");
combo2.Items.Add("Slama :p");
combo2.Margin = new Thickness(50, 50, 0, 0);
combo2.Foreground = new SolidColorBrush(Colors.Red);
      //add to canvas
canv.Children.Add(combo2);

我希望它会有用