简体   繁体   English

Combobox 项目来源绑定不起作用

[英]Combobox Itemsource Binding does not work

I'm trying to fill my Combobox ItemsSource using Binding in Xaml with a collection of data ObservableCollection but I always get the Combobox ItemsSource null. I'm trying to fill my Combobox ItemsSource using Binding in Xaml with a collection of data ObservableCollection but I always get the Combobox ItemsSource null.

WPF UserControl Cs Code: ( Update the code ) 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 Code: ( Updated my code ) 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>

Class User Class 用户

 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;
           }
    }

What is the source of this problem?这个问题的根源是什么?

SelectedIndex 总是取 -1

Discarding unnecessary (which is not relevant to the question or has syntax errors), your example with a little formatting works fine.丢弃不必要的(与问题无关或有语法错误),您的示例带有一点格式就可以了。

XAML: 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>

Code-behind:代码隐藏:

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;
    }
}

Result:结果:

在此处输入图像描述

Remarks:评论:

Your您的

Console.WriteLine(ComboBoxUsers.Items.Count); // always 0 Console.WriteLine(ComboBoxUsers.ItemsSource); // always null

because you use Binding .因为您使用Binding You needn't access ItemsSource or Items.Count through ComboBox - you should use binded collection Users (eg Users.Count ) to manipulate or get ComboBox content.您无需通过ComboBox访问ItemsSourceItems.Count - 您应该使用绑定的集合Users (例如Users.Count )来操作或获取 ComboBox 内容。

EDIT.编辑。

About SelectedItem .关于SelectedItem You should define for yourself, you want use Bindings or work with ComboBox directly .您应该自己定义,您想使用绑定直接使用 ComboBox。

Binding push you to NOT use ComboBox.SelectedItem/Index/Value whatever.绑定推动您不要使用ComboBox.SelectedItem/Index/Value无论如何。 Even not access ComboBoxUsers to get some data.甚至不访问ComboBoxUsers来获取一些数据。 Binding is closely related to, for example, the MVVM Pattern .绑定与例如MVVM Pattern密切相关。 If you decided to use Bindings - forget about accessing directly to ComboBox or it data properties SelectedItem/Index/Value or similar.如果您决定使用绑定 - 忘记直接访问ComboBox或其数据属性SelectedItem/Index/Value或类似。

If you use Bindings - you should create a property (eg SelectedUser ) for SelectedItem (same as you create property Users for your ItemsSource ) and bind to it:如果您使用 Bindings - 您应该为 SelectedItem 创建一个属性(例如SelectedUser )(与为您的 ItemsSource 创建属性Users相同)并绑定到它:

XAML (introducing binding for SelectedItem property and SelectionChanged handler) : 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>

Code-behind (introducing property SelectedUser and OnUserSelectionChanged handler) :代码隐藏(引入属性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;
    }
}

Repeat same algorithm for each property you wish to Bind (eg SelectedIndex ):对您希望绑定的每个属性重复相同的算法(例如SelectedIndex ):

SelectedIndex="{Binding SelectedUserIndex}"
public int SelectedUserIndex { get; set; }

Result:结果:

在此处输入图像描述

Decide for yourself, what you need.自己决定,你需要什么。 Nice modern Bindings or old boring (sender as ComboBox).SelectedItem .漂亮的现代Bindings或旧的无聊(sender as ComboBox).SelectedItem

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM