组合框项目源绑定不起作用
Posted
技术标签:
【中文标题】组合框项目源绑定不起作用【英文标题】:Combobox Itemsource Binding does not work 【发布时间】:2022-01-07 02:33:50 【问题描述】:我正在尝试使用 Xaml 中的 Binding 使用数据集合 ObservableCollection
填充我的 Combobox ItemsSource,但我总是得到 Combobox ItemsSource null 。
WPF UserControl Cs 代码:(更新代码)
public ObservableCollection<User> users get; set;
public partial class MainWindow : Window
InitializeComponent();
User user1 = new User("Mariah", 15);
User user2 = new User("John", 19 );
users = new ObservableCollections<User>();
users.Add(user1);
users.Add(user2);
this.DataContext = this;
Console.WriteLine(ComboBoxUsers.Items.Count); // always 0
Console.WriteLine(ComboBoxUsers.ItemsSource); // always null
WPF UserControl Xaml 代码:(更新了我的代码)
<ComboBox SelectedIndex = "0" x:Name="ComboBoxUsers" ItemsSource="Binding users, UpdateSourceTrigger=PropertyChanged" FontFamily="Arial" FontSize="11" Grid.Row="3" Height="30" Margin="10,5,5,5">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<Image IsEnabled="False" Source="Binding Image"/>
<TextBlock x:Name="textblock" IsEnabled="False" Text="Binding Name />
</StackPanel>
<DataTemplate.Resources>
<Style TargetType="ComboBoxItem">
<Setter Property="IsEnable" Value="Binding IsEnable"/>
</Style>
</DataTemplate.Resources>
</DataTemplate>
</ComboBox.ItemTemplate>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem" BasedOn="StaticResource x:Type ComboBoxItem">
<Setter
Property="Visibility"
Value="Binding IsHidden" />
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
班级用户
public class User
public string Name get; set;
public int Age get; set;
public User(string name, int age)
this.Name = name;
this.Age = age;
这个问题的根源是什么?
【问题讨论】:
我已经添加了,抱歉我的代码没有完成,我已经更新了我的问题 我已经将combobox的ItemsSource
设置为Users
是的,我已经添加了这部分代码ComboBoxUsers.ItemsSource = users;
进行测试,也许我的问题不是很清楚,后面代码中的绑定(C# 代码)运行良好,但问题只出现在 xaml代码
另请注意,ItemsSource Binding 上的UpdateSourceTrigger=PropertyChanged
无效,应将其删除,即使 Binding 有效。
好的,但是我想先解决我的问题,请看更新
【参考方案1】:
丢弃不必要的(与问题无关或有语法错误),您的示例稍加格式化即可正常工作。
XAML:
<ComboBox x:Name="ComboBoxUsers"
ItemsSource="Binding Users"
FontFamily="Arial"
FontSize="11"
Grid.Row="3"
Height="30"
Margin="10,5,5,5">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<TextBlock IsEnabled="False"
Text="Binding Name" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
代码隐藏:
public class User
public string Name get;
public int Age get;
public User(string name, int age)
Name = name;
Age = age;
public partial class MainWindow : Window
public ObservableCollection<User> Users get;
public MainWindow()
InitializeComponent();
// Initialize collection with some items
Users = new ObservableCollection<User>
new User("Mariah", 15),
new User("John", 19)
;
DataContext = this;
结果:
备注:
你的
Console.WriteLine(ComboBoxUsers.Items.Count); // always 0 Console.WriteLine(ComboBoxUsers.ItemsSource); // always null
因为您使用绑定。您无需通过ComboBox
访问ItemsSource
或Items.Count
- 您应该使用绑定 集合Users
(例如Users.Count
)来操作或获取ComboBox 内容。
编辑。
关于SelectedItem
。您应该自己定义,您想使用 Bindings 还是直接使用 ComboBox。
Binding 促使你不要使用 ComboBox.SelectedItem/Index/Value
任何东西。甚至不访问ComboBoxUsers
来获取一些数据。 Binding 与MVVM Pattern 等密切相关。如果您决定使用绑定 - 忘记直接访问 ComboBox
或它的数据属性 SelectedItem/Index/Value
或类似的。
如果您使用绑定 - 您应该为 SelectedItem 创建一个属性(例如 SelectedUser
)(与为您的 ItemsSource 创建属性 Users
相同)并绑定到它:
XAML (引入SelectedItem
属性和SelectionChanged
处理程序的绑定):
<ComboBox x:Name="ComboBoxUsers"
ItemsSource="Binding Users"
SelectedItem="Binding SelectedUser"
SelectionChanged="OnUserSelectionChanged"
FontFamily="Arial"
FontSize="11"
Grid.Row="3"
Height="30"
Margin="10,5,5,5">
</ComboBox>
代码隐藏 (引入属性SelectedUser
和OnUserSelectionChanged
处理程序):
public partial class MainWindow : Window
public ObservableCollection<User> Users get;
// Here would be stored your Binded selected item
public User SelectedUser get; set;
// And here is your handler when selection changed
private void OnUserSelectionChanged(object sender, SelectionChangedEventArgs e)
// SelectedUser property stores selected in ComboBox item,
// so you can use it directly
_ = MessageBox.Show(SelectedUser.Name);
// Even if you wish to get directly - it is possible
// (thanks to @Clemens):
var selectedUser = (sender as ComboBox).SelectedItem as User;
var selectediIndex = (sender as ComboBox).SelectedIndex;
public MainWindow()
InitializeComponent();
Users = new ObservableCollection<User>
new User("Mariah", 15),
new User("John", 19)
;
DataContext = this;
对您希望绑定的每个属性重复相同的算法(例如SelectedIndex
):
SelectedIndex="Binding SelectedUserIndex"
public int SelectedUserIndex get; set;
结果:
自己决定,你需要什么。漂亮的现代绑定或旧无聊(sender as ComboBox).SelectedItem
。
【讨论】:
我没有实现 INotifyPropertyChanged 接口来简化示例。 首先,我仍然得到空值的组合框..你的解决方案对我不起作用。其次,您错过了 StackPanel 中的图像控件,因此可能在代码和结果中进行了一些更改。 如果按你说的那样工作,那么尝试添加 `ComboBoxUsers.SelectedItem` 并且你会看到该项目为空(SelectedIndex
在 Xaml 代码中设置为 0)
你说的不对,因为Combobox
在代码中仍然为空,我无法访问SelectedItem
或SelectedIndex
@abdou31 试着把注意力集中在你问的问题上。正如您所展示的那样,Image 元素与显示 User 类的实例无关。说“ComboBox 为空”完全没有意义。请记住,当您在代码中设置 ItemsSource 时,您是从 MainWindow 构造函数访问它。此答案中显示的示例有效。可能只是接受它并从那里开始。如果您在绑定 SelectedItem 或 SelectedIndex 时遇到问题,请提出另一个问题。以上是关于组合框项目源绑定不起作用的主要内容,如果未能解决你的问题,请参考以下文章