我正在尝试建立付款信息表并遇到一些麻烦。
XAML的层次结构:TabControl - >网格 - >组合框
我还需要将数据存储在Profile类的实例中,调用此配置文件1(配置文件存储在静态Observable Collection中,调用此配置文件),程序将包含多个配置文件。
问题:
我很难将这个绑定到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;
}
}
}));
}
答案 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" } }
}
}