【问题标题】:Curious behavior with ComboBox in UWP - SelectedItem & ItemsSourceUWP 中 ComboBox 的奇怪行为 - SelectedItem & ItemsSource
【发布时间】:2020-05-26 10:37:20
【问题描述】:

希望你们一切都好。 我在 UWP 应用程序中遇到了 2 个与 ComboBox 相关的问题。

  1. 如果属性 ItemsSource 绑定到实现 INotifyPropertyCollectionChanged 的集合,则永远不会完全加载列表。我只有 2、3 或 4 个第一个项目……取决于时间。当同一个集合绑定到 DataGrid 时没问题,所以我认为我的集合是正确构建的。作为一种解决方法(代码隐藏),我首先加载我的集合(在任务中)并在任务完成时设置 ItemsSource 属性。此解决方案有效,但我想少做一些代码隐藏的事情。
  2. SelectedItem 属性上的绑定似乎仅适用于 ReferenceEquals,我的集合中的项目类型基于 ID 实现 Equals,并且已在控制台应用程序中单独测试并成功。作为一种解决方法(代码隐藏),加载列表后,我将绑定到 SelectedItem 的属性更改如下:
        Users.TaskFill.ContinueWith(t => BaseItemCollection.UserInterfaceAction.Invoke(() =>
        {
            if (Item?.Manager != null) Item.Manager = t.Result.FirstOrDefault(i => i.Equals(Manager));
            ComboBoxManager.SetBinding(ComboBox.ItemsSourceProperty, this, "Users", BindingMode.TwoWay);
            ComboBoxManager.SetBinding(Selector.SelectedItemProperty, "Manager", BindingMode.TwoWay);
        }));
  • Users 是我的集合(异步填充),用作 ComboBox 的源
  • SetBinding 是我自己创建的一种自定义扩展方法,用于在单行代码隐藏代码中设置绑定(如下所示):
public static class ExtensionMethods
{
    #region DependencyObject
    public static void SetBinding(this DependencyObject dependencyObject, DependencyProperty dependencyProperty, object source, string propertyName, BindingMode mode)
    {
        var binding = new Binding()
        {
            Source = source,
            Path = new PropertyPath(propertyName),
            Mode = mode
        };
        BindingOperations.SetBinding(dependencyObject, dependencyProperty, binding);
    }
    public static void SetBinding(this DependencyObject dependencyObject, DependencyProperty dependencyProperty, string propertyName, BindingMode mode)
    {
        var binding = new Binding()
        {
            Path = new PropertyPath(propertyName),
            Mode = mode
        };
        BindingOperations.SetBinding(dependencyObject, dependencyProperty, binding);
    }
    #endregion
}

如何在不需要这些变通方法的情况下从 XAML 中实现这一点?多年来,我一直能够获得与 WPF 一起使用的类似配置,但我真的在 UWP 上苦苦挣扎......

提前感谢您的帮助。

【问题讨论】:

  • 是的面板。对于 SelectedItem,它仍然使用 ReferenceEquals,但这没什么大不了的。我的代码比以前少。感谢您的帮助。

标签: c# uwp binding


【解决方案1】:

如果属性 ItemsSource 绑定到实现 INotifyPropertyCollectionChanged 的​​集合,则永远不会完全加载列表。

如果您的收藏不是字符串,则需要指定DisplayMemberPath,请检查以下代码。并请检查收藏是否有价值。对于我实现INotifyPropertyCollectionChanged 的测试集合适用于ComboBox

<ComboBox
    x:Name="cmbCountry"
    Grid.Row="4"
    Width="292"
    Height="32"
    Margin="28,0,0,0"
    HorizontalAlignment="Left"
    VerticalAlignment="Center"
    DisplayMemberPath="FirstName"
    ItemsSource="{Binding MyItems}"
    PlaceholderText="Select Country ..."
    />

ComboBox 的奇怪行为

ComboBox 的默认 ItemsPanelTemplate 是 CuriousPanel,可以在触摸设备中实现滚动循环。如果你不想使用它,你可以用 StackPanel 替换它

<ComboBox.ItemsPanel>
    <ItemsPanelTemplate>
        <StackPanel />
    </ItemsPanelTemplate>
</ComboBox.ItemsPanel>
<ComboBox.ItemTemplate>

属性 SelectedItem 上的绑定似乎仅适用于 ReferenceEquals,

SelectedItem 不是ComboBox 显示字段,它是一个完整的用户对象。您可以在SelectedItem 绑定属性设置方法中获取选择用户。以下是您可以参考的完整代码。

public sealed partial class TestPage : Page, INotifyPropertyChanged
{
    private User _selecteduser;

    public TestPage()
    {
        this.InitializeComponent();

        _myItems = new ObservableCollection<User>
        {
            new User{UserId=1,FirstName="Fay",LastName="Wang",City="Delhi",State="DEL",Country="INDIA"},
            new User{UserId=2,FirstName="Mark",LastName="Liu",City="New York", State="NY", Country="USA"},
            new User{UserId=3,FirstName="Rich",LastName="Cai",City="Philadelphia", State="PHL", Country="USA"},
            new User{UserId=4,FirstName="Eveia",LastName="Dong",City="Noida", State="UP", Country="CANADA"}}
        };

        this.DataContext = this;
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)//string propertyName
    {
        if (PropertyChanged != null)

        {
            PropertyChangedEventArgs args = new PropertyChangedEventArgs(propertyName);
            this.PropertyChanged(this, args);
        }
    }

    public ObservableCollection<User> Users
    {
        get
        { return _myItems; }
        set
        {
            _myItems = value;
            OnPropertyChanged("Users");
        }
    }
    private ObservableCollection<User> _myItems;

    public User SelectedUser
    {
        get
        {
            return _selecteduser;
        }
        set
        {
            _selecteduser = value;


            OnPropertyChanged("SelectedUser");
        }
    }
}

Xaml

<ComboBox
    x:Name="cmbCountry"
    Grid.Row="4"
    Width="292"
    Height="32"
    Margin="28,0,0,0"
    HorizontalAlignment="Left"
    VerticalAlignment="Center"
    DisplayMemberPath="FirstName"
    ItemsSource="{Binding Users}"
    PlaceholderText="Select User..."
    SelectedItem="{Binding SelectedUser, Mode=TwoWay}"
    />

【讨论】:

    猜你喜欢
    • 2014-12-10
    • 2013-09-22
    • 1970-01-01
    • 2020-10-06
    • 2016-05-15
    • 2017-04-30
    • 2010-12-08
    • 2011-07-11
    • 2014-07-27
    相关资源
    最近更新 更多