【问题标题】:Conditional combobox binding with string storage带字符串存储的条件组合框绑定
【发布时间】:2015-03-29 08:44:52
【问题描述】:

我正在尝试构建付款信息表单,但遇到了一些麻烦。

  1. 我有这个“国家/地区”组合框,可以让用户选择国家/地区。
  2. 我还有另一个“州”组合框,可让用户选择国家/地区的州。
  3. 由于每个国家/地区都有不同的州,ItemSource 取决于“国家/地区”组合框的选择。
  4. XAML 的层次结构:TabControl -> 网格 -> 组合框

  5. 我还需要将数据存储在一个Profile类的实例中,调用这个profile 1(profile存储在一个静态的Observable Collection中,调用这个Profiles),程序会包含多个profile。

问题:

我很难将此绑定到 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”的解决方案结合使用,非常感谢! 出于某种原因,如果我使用“状态”组合框的原始属性,则所选选项不会在运行时显示出来。

主要思想是使用 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;
            }
        }
    }));
}

【问题讨论】:

    标签: c# wpf xaml combobox


    【解决方案1】:

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

    可能的解决方案:提供public IList&lt;string&gt; States 属性以将您的状态组合框绑定到(我认为您不必在此处使用 ObservableCollections)并在Country 的设置器中将列表设置为适当的状态列表。比如:

    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 子句:

    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" } }
       }
    }
    

    【讨论】:

    • 是的,谢谢你的推荐,我有点时间限制,而且学习曲线似乎有点陡峭(我从 C# 的 0 知识开始),所以我不得不把它暂停了一会儿。您是否会推荐在线或实体书中的任何特定材料以加快学习过程?甚至可能是整个 WPF 和 XAML?
    • 在此之前我曾尝试在网上自己做一些研究,我发现有很多关于 C#、MVVM 和 ASP.NET 的综合资料。然而,当使用 WPF 处理 MVVM 时,材料似乎是分散的。通常我更喜欢来自复数视觉或 lynda.com 的视频,因为它们很容易在短时间内完成,但我想我只能通过这些主题的长篇阅读。
    • 我对 c#/wpf 的了解也来自网络上的零散信息,实际上主要是这个网站,所以我不能推荐任何书籍/教程..
    • 好的,感谢您的宝贵时间,它为我省去了很多麻烦。我会投票给你,但我没有足够的代表这样做:(
    猜你喜欢
    • 2013-09-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-01
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    • 2016-03-27
    • 2012-03-26
    相关资源
    最近更新 更多