组合框项目源绑定不起作用

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 访问ItemsSourceItems.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>

代码隐藏 (引入属性SelectedUserOnUserSelectionChanged 处理程序)

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在代码中仍然为空,我无法访问SelectedItemSelectedIndex @abdou31 试着把注意力集中在你问的问题上。正如您所展示的那样,Image 元素与显示 User 类的实例无关。说“ComboBox 为空”完全没有意义。请记住,当您在代码中设置 ItemsSource 时,您是从 MainWindow 构造函数访问它。此答案中显示的示例有效。可能只是接受它并从那里开始。如果您在绑定 SelectedItem 或 SelectedIndex 时遇到问题,请提出另一个问题。

以上是关于组合框项目源绑定不起作用的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 WHERE 子句在我的组合框中不起作用

在两个控件之间共享绑定源不起作用

剑道组合框需要验证不起作用

WPF - 嵌套列表框绑定不起作用

Metro / Windows Store App:相对图像源绑定不起作用?

即使我在设计器中更改了高度,组合框下拉菜单也不起作用