【问题标题】: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 有效。
  • 好的,但是我想先解决我的问题,请看更新

标签: c# wpf xaml


【解决方案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 来获取一些数据。 BindingMVVM 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 时遇到问题,请提出另一个问题。
猜你喜欢
  • 1970-01-01
  • 2011-05-20
  • 1970-01-01
  • 1970-01-01
  • 2014-05-23
  • 2018-07-27
  • 2013-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多