条件组合框与字符串存储绑定

时间:2015-03-29 08:44:52

标签: c# wpf xaml combobox

我正在尝试建立付款信息表并遇到一些麻烦。

  1. 我有这个“国家”组合框,让用户选择国家。
  2. 我还有另一个“State”ComboBox,允许用户选择国家/地区的状态。
  3. 因为每个国家/地区都有不同的状态,所以ItemSource取决于“Country”ComboBox的选择。
  4. XAML的层次结构:TabControl - >网格 - >组合框

  5. 我还需要将数据存储在Profile类的实例中,调用此配置文件1(配置文件存储在静态Observable Collection中,调用此配置文件),程序将包含多个配置文件。

  6. 问题:

    我很难将这个绑定到State ComboBox,因为我是WPF的新手,所以任何帮助都会非常感激。非常感谢。

    问题是我不知道如何使State ComboBox ItemSource条件绑定到ComboBoxSource类成员,同时与各个配置文件的State属性同步。 (它需要通过读取字符串的值来同步)

    解决方案:

    <ComboBox Name="Country" ItemsSource="{Binding Source={x:Static loc:ComboBoxItemSource.Countries}}" SelectedItem="{Binding Path=Country, Mode=TwoWay}">
    <ComboBox Name="State" ItemsSource="{Binding States, Mode=TwoWay}" SelectedItem="{Binding Path=State, Mode=TwoWay}">
    

    将此与“stijn”的解决方案结合使用,非常感谢! 出于某种原因,如果我使用“State”ComboBox的原始属性,则所选选项将无法在运行时显示。

    主要思想是使用SelectedItem而不是SelectedValue和SelectedValuePath

    以下原始代码:

    XAML:

    <ComboBox Name="Country" Grid.Row="0" Grid.Column="3" SelectedValuePath="Content" SelectedValue="{Binding Country, Mode=TwoWay}" SelectionChanged="Country_SelectionChanged">
        <ComboBoxItem>USA</ComboBoxItem>
        <ComboBoxItem>Canada</ComboBoxItem>
        <ComboBoxItem>Japan</ComboBoxItem>
    </ComboBox>
    <ComboBox Name="State" Grid.Row="1" Grid.Column="3" SelectedValuePath="Content" SelectedValue="{Binding State, Mode=TwoWay}" ItemsSource="{Binding Source={x:Static loc:ComboBoxItemSource.USStates}}">
    

    代码隐藏:

    class Profile
    {
        //default values
        private string country = "Canada";
    
        public string Country
        {
            get { return country; }
            set 
            {
                country = value;
                this.OnPropertyChanged();
            }
        }
        //default values
        private string state = "CA2";
    
        public string State
        {
            get { return state; }
            set 
            { 
                state = value;
                this.OnPropertyChanged();
            }
        }
    }
    
    public class ComboBoxItemSource
    {
        public static MTObservableCollection<string> USStates = new MTObservableCollection<string> { "VA", "DC" };
        public static MTObservableCollection<string> CanadaStates = new MTObservableCollection<string> { "CA1", "CA2" };
        public static MTObservableCollection<string> Countries = new MTObservableCollection<string> { "USA", "Canada", "Japan" };       
    }
    
    //Some method in the main class:
    private void Country_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        Dispatcher.BeginInvoke(new Action(() =>
        {
            if (Profiles.Count > 0)
            {
                //the ComboBox is inside a grid, which is inside a TabControl that displays all the profiles
                Profile item = (Profile)((Grid)((ComboBox)sender).Parent).DataContext;
                ContentPresenter cp = Tabs.Template.FindName("PART_SelectedContentHost", Tabs) as ContentPresenter;
                ComboBox g = Tabs.ContentTemplate.FindName("State", cp) as ComboBox;
                if (g.ItemsSource == null) { return; }
                if (((ComboBox)sender).Text == "USA")
                {
                    g.ItemsSource = ComboBoxItemSource.USStates;
                }
                else if (((ComboBox)sender).Text == "Canada")
                {
                    g.ItemsSource = ComboBoxItemSource.CanadaStates;
                }
            }
        }));
    }
    

1 个答案:

答案 0 :(得分:1)

无需“有条件地绑定”静态变量,也不需要后面的代码。我建议你在互联网上搜索“MVVM”并阅读一些基本的教程。

可能的解决方案:提供一个public IList<string> States属性来绑定你的状态组合框(我认为你不必在这里使用ObservableCollections)并在Country的setter中将列表设置为适当的状态名单。类似的东西:

public string Country
{
    get { return country; }
    set 
    {
        country = value;
        SetStatesForCountry( value );
        this.OnPropertyChanged();
    }
}

private IList<string> states;

public IList<string> States
{
  get{ return states; }
  private set { states = value; this.OnPropertyChanged(); } 
}

private void SetStatesForCountry( string selectedCountry )
{
  IList<string> found;
  if( StatesPerCountry.Map.TryGetValue( selectedCountry, out found ) )
  {
    States = found;
  }
  else
  {
    States = null; //or you could set it to "not applicable" or so
  }
}

注意我使用字典将状态映射到国家/地区,不需要有大量的if / else clasues:

public class StatesPerCountry
{
   public static IDictionary<string,IList<string>> Map = new
     IDictionary<string,IList<string>>
   {
     { "USA", new List<string>{ "a", "b", "c" } },
     { "CAN", new List<string>{ "a", "b", "c" } },
     { "Japan", new List<string>{ "a", "b", "c" } }
   }
}