wpf combobox 页面上怎么绑定值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了wpf combobox 页面上怎么绑定值相关的知识,希望对你有一定的参考价值。

要实现的功能是 两个下拉列表动态联动 请高手吧代码写详细一点 我是新手

参考技术A xaml:

<StackPanel Orientation="Horizontal">
<ComboBox Name="cb1" ItemsSource="Binding" Width="200" Height="30" SelectionChanged="Cb1_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="Binding Name"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ComboBox Name="cb2" ItemsSource="Binding" Width="200" Height="30">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="Binding Name"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>

xaml.cs:

public MainWindow() //构造函数

InitializeComponent();

var provinces = new List<Province>

new Province

Name="山西省",
Cities = new List<City>

new CityName="太原市",new CityName="大同市",new CityName="运城市",new CityName="榆次市"

,
new Province

Name="陕西省",
Cities = new List<City>

new CityName="西安市",new CityName="宝鸡市 ",new CityName="渭南市 ",new CityName="咸阳市 "


;
cb1.DataContext = provinces;


private void Cb1_SelectionChanged(object sender, SelectionChangedEventArgs e)

var combobox = sender as ComboBox;
if (combobox != null)

var province = combobox.SelectedItem as Province;
cb2.DataContext = province.Cities;
cb2.SelectedIndex = 0;




辅助类:

public class Province

public string Name get; set;

public List<City> Cities get; set;


public class City

public string Name get; set;
本回答被提问者采纳
参考技术B dgfhdghdghdhgdghdhfdghdghdghdfghdfghdfghdfhgdfghdfghdghgfhhgfdhfdhgdfghdfghdfghdghfdghfdghdfghfdgdhdfghdfghfdghdfghfgdhdfhfdghfddfghfdghdfghdfghdfghdfhfdghfgdfghfghfghfghfghfgfghfggfdgfhfdhdghfdhfdhfhfghfghfhfghfhfhfhfdfdhdhfdhghgfhfdhgfdghfghfghfdghfghfdh

如何防止 ComboBox 中的 NewItemPlaceholder 行绑定到与 WPF 中的 DataGrid 相同的 DataTable

【中文标题】如何防止 ComboBox 中的 NewItemPlaceholder 行绑定到与 WPF 中的 DataGrid 相同的 DataTable【英文标题】:How to prevent NewItemPlaceholder row in a ComboBox bound to the same DataTable as a DataGrid in WPF 【发布时间】:2012-02-23 04:56:14 【问题描述】:

我是一个使用页面的向导式应用程序,用户可以通过“下一个”和“上一个”按钮在它们之间导航,也可以使用导航栏直接访问某些页面。

在一页(我将其称为“网格页”)上,我有一个绑定到 DataTable 的 DataGrid。 DataTable 中有一些初始数据,但使用 DataGrid,用户可以根据需要添加、编辑和删除行。 在下一页(我称之为“组合框页面”)有一个 ComboBox,它与网格页面上的 DataGrid 绑定到相同的 DataTable。 两个页面都使用相同的对象作为数据上下文。

如果我直接跳到组合框页面,一切正常,组合框在 DataTable 中的每一行都有一个条目,就像它应该的那样。现在我导航到网格页面并且没有触摸那里的任何东西,然后再次转到组合框页面。现在 ComboBox 显示一个新项目,一个 NewItemPlaceholder。显然,这是因为 DataGrid 将 UserCanAddRows 设置为 true,因此会为新项目显示占位符行。但这应该只涉及 DataGrid 而不是绑定的 DataTable,所以在我看来这是一个错误,或者至少是一个绝对可怕的设计。

当然,我不想在我的 ComboBox 中使用 NewItemPlaceholder(选择它会导致很多问题)。那么如何防止它显示在 ComboBox 中呢?

更新:与此同时,我发现占位符项目不在 DataTable 中作为一行,这使得它更加奇怪,除非 DataTable 中有一个标志显示“此表中有一个 NewItemPlaceholder”但是本身不是一行。此外,当我注册到 ComboBox 的 Initialized 事件时,我有 2 个我正在寻找的项目,当我注册到 Loaded 事件时,我也有 NewItemPlaceholder,因此必须在这两个事件之间添加它。

【问题讨论】:

【参考方案1】:

使用 CollectionViewSource 绑定一个控件(Combobox)和 ViewModel 中定义的集合属性绑定另一个控件(Datagrid)。

ViewModel 中的属性:

private List<Rate> _rate = new List<Rate>();
   public List<Rate> RatePlans
     
       get  return _rate; 
       set
       
         _rate = value;
          OnPropertyChanged("RatePlans");
       
     

然后在 XAML 中:

<UserControl >
      <UserControl.Resources >
            <CollectionViewSource Source="Binding RatePlans" x:Key="RatesSource" />
        </UserControl.Resources>
      <Grid Name="LayoutGrid">
      <Grid.RowDefinitions>
         <RowDefinition/>
         <RowDefinition/>
      </Grid.RowDefinitions>
      <ComboBox Grid.Row="0" DisplayMemberPath="RatePlanName"  ItemsSource="Binding Source=StaticResource RatesSource" HorizontalAlignment="Stretch"/>
    <DataGrid Grid.Row="1" HorizontalAlignment="Stretch" CanUserAddRows="True" AutoGenerateColumns="False"  ItemsSource="Binding RatePlans">
     <DataGrid.Columns>
      <DataGridTextColumn Binding="Binding RatePlanName" Header="Rate Plan" />
      <DataGridTextColumn Binding="Binding RoomType" Header="Room Type" />
      <DataGridTextColumn Binding="Binding Price" Header="Price"/>
      </DataGrid.Columns>
</DataGrid>
</Grid>
</UserControl>

【讨论】:

【参考方案2】:

使用 CollectionViewSource。当多个控件共享一个集合的相同视图时会出现此问题,例如当一个集合在一种情况下绑定到 DataGrid 而在另一种情况下绑定到 ComboBox。如果 DataGrid 允许用户添加项目(即 DataGrid 的 CanUserAddRows 为 true),则 NewItemPlaceholder 可能已添加到视图中。尝试类似

<UserControl >
<UserControl.Resources >
    <CollectionViewSource Source="Binding MyCollection"
             x:Key="SourceWithoutNewItemPlaceholder" />
</UserControl.Resources>

  <Grid Name="LayoutGrid" >

   <ComboBox ItemsSource=Binding Source=StaticResource SourceWithoutNewItemPlaceholder >

  </Grid>
</UserControl>

【讨论】:

【参考方案3】:

经过几次失败的尝试,我找到了 2 个解决方案:

1) 在页面的 Loaded 事件中,我在后面的代码中进行了绑定,不是绑定到 DataTable 本身,而是绑定到 DataTable.ToList。如果我这样做,NewItemPlaceholder 将不会出现。

2) 在视图模型中,我创建了一个新属性,该属性返回 DataTable.ToList 并绑定到它。这样我就可以在 XAML 中进行绑定了。

仅供参考,不起作用的方法:ComboBox 上的 Filter 属性引发 NotSupportedException,似乎 DataTable 不支持此操作。在 ComboBox 的 Loaded 事件中删除 NewItemPlaceholder 也不起作用,因为在设置 ItemsSource 时无法删除项目。离开带有数据网格的页面时删除 NewPlaceHolderItem 也不起作用,因为我找不到它的位置(它不在 DataTable 或 DataTable 的视图中)

【讨论】:

以上是关于wpf combobox 页面上怎么绑定值的主要内容,如果未能解决你的问题,请参考以下文章

在wpf中怎么绑定comboBox的值

Wpf的comboBox怎么绑定数据?

WPF DataTemplate ComboBox 绑定问题

WPF Combobox数据绑定Binding

如何防止 ComboBox 中的 NewItemPlaceholder 行绑定到与 WPF 中的 DataGrid 相同的 DataTable

WPF——ComboBox控件怎么绑定数据