【问题标题】:How to set ComboBoxItem property?如何设置 ComboBoxItem 属性?
【发布时间】:2021-12-03 03:46:00
【问题描述】:

当它被选中时,我试图在 Combobox 中隐藏一个项目,这就是我的代码现在的样子:

VeiwModel.cs

        public class SortList
        {
            public string Key { get; set; }
            public string Value { get; set; }
            public bool IsSelectable { get; set; }
        }
        private void InitSortList()
        {
            ObservableCollection<SortList> sl = new ObservableCollection<SortList>();

            foreach(var i in defaultSortList)
            {
                SortList s = new SortList();
                s.Key = i.Key.ToString();
                s.Value = i.Value.ToString();
                s.IsSelectable = false;
                sl.Add(s);
            }

            _items = sl;
        }

        private ObservableCollection<SortList> _items = new ObservableCollection<SortList>();
        public ObservableCollection<SortList> Items
        {
            get { 
                return _items; }
        }


        private SortList _selectedSort;
        public SortList SelectedItem
        {
            get { return _selectedSort; }
            set
            {
                if(_selectedSort != value)
                {
                    _selectedSort = value;
                    _selectedSort.IsSelectable = false;
                    PropertyChanged(this, new PropertyChangedEventArgs("SelectedItem"));
                }
            }
        }

MainPage.xaml

 <ComboBox Header="Sort 1" HorizontalAlignment="Stretch"
                                                  Name="Sort_1" SelectionChanged="comboSelectionChanged"
                                                  ItemsSource="{Binding Items, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                                 SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
                                                  SelectedValuePath="Key"
                                            DisplayMemberPath="Value" 
                                                  >
                                            <ComboBox.ItemContainerStyle>
                                                <Style TargetType="ComboBoxItem" BasedOn="ComboBoxIem">
                                                    <Setter
                                                         Property="IsEnabled"
                                                         Value="{Binding Items.IsSelectable, Mode=TwoWay}" />

//Binding IsSelectable doesnt work either
                                                   
                                                </Style>
                                            </ComboBox.ItemContainerStyle>
                                        </ComboBox>

我不确定 Binding 部分如何在 Setter 属性上工作,因为我认为它没有从 Items 类中获取 IsSelectable 属性......

【问题讨论】:

    标签: c# xaml windows-runtime winrt-xaml winui-3


    【解决方案1】:

    请参考文档here,UWP 不支持样式设置器中的绑定。绑定ItemContainerStyle样式时不会生效。

    Windows Presentation Foundation (WPF) 和 Microsoft Silverlight 支持使用绑定表达式为样式中的 Setter 提供值的能力。 Windows 运行时不支持 Setter.Value 的 Binding 用法(Binding 不会计算并且 Setter 没有效果,您不会收到错误,但也不会获得所需的结果)。当您从 Windows Presentation Foundation (WPF) 或 Microsoft Silverlight XAML 转换 XAML 样式时,请将任何 Binding 表达式用法替换为设置值的字符串或对象,或将值重构为共享 {StaticResource} 标记扩展值而不是 Binding 获得的值。

    对于这种情况,解决方法可能是一个辅助类,它带有绑定源路径的附加属性。它将在 helper 属性的 PropertyChangedCallback 后面的代码中创建绑定表达式。

    我已经编辑了你的代码和xaml,请参考下面的代码实现。

    <Page.DataContext>
        <local:ViewModel />
    </Page.DataContext>
    <Grid>
        <ComboBox
            Name="Sort_1"
            HorizontalAlignment="Stretch"
            DisplayMemberPath="Value"
            Header="Sort 1"
            ItemsSource="{Binding Items, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
            SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
            SelectedValuePath="Key"
            SelectionChanged="comboSelectionChanged">
            <ComboBox.ItemContainerStyle>
                <Style TargetType="ComboBoxItem">
                    <Setter Property="local:BindingHelper.IsEnable" Value="IsSelectable" />
                </Style>
            </ComboBox.ItemContainerStyle>
        </ComboBox>
    </Grid>
    

    C# 代码

    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
    
        }
    
        private void comboSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
    
        }
    }
    
    public class BindingHelper
    {
        public static string GetIsEnable(DependencyObject obj)
        {
            return (string)obj.GetValue(IsEnableProperty);
        }
        public static void SetIsEnable(DependencyObject obj, string value)
        {
            obj.SetValue(IsEnableProperty, value);
        }
        // Using a DependencyProperty as the backing store for IsEnable.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsEnableProperty =
            DependencyProperty.RegisterAttached("IsEnable", typeof(string), typeof(BindingHelper), new PropertyMetadata(null, GridBindingPathPropertyChanged));
    
        private static void GridBindingPathPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            var propertyPath = e.NewValue as string;
            if (propertyPath != null)
            {
                var bindingProperty =
                    e.Property == IsEnableProperty
                    ? ComboBoxItem.IsEnabledProperty
                    : null;
                BindingOperations.SetBinding(
                    obj,
                    bindingProperty,
                    new Binding { Path = new PropertyPath(propertyPath) });
            }
        }
    }
    
    public class ViewModel : INotifyPropertyChanged
    {
        public class SortList : INotifyPropertyChanged
        {
            public string Key { get; set; }
            public string Value { get; set; }
            private bool _isSelectable;
            public bool IsSelectable
            {
                get { return _isSelectable; }
                set
                {
                    _isSelectable = value;
                    OnPropertyChanged();
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            private void OnPropertyChanged([CallerMemberName] string PropertyName = null)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
                }
            }
        }
        public ViewModel()
        {
            defaultSortList = new Dictionary<string, string>();
            defaultSortList.Add("0", "item");
            defaultSortList.Add("1", "item1");
            defaultSortList.Add("2", "item2");
            defaultSortList.Add("3", "item3");
    
            InitSortList();
        }
        private Dictionary<string, string> defaultSortList;
        private void InitSortList()
        {
            ObservableCollection<SortList> sl = new ObservableCollection<SortList>();
    
            foreach (var i in defaultSortList)
            {
                SortList s = new SortList();
                s.Key = i.Key.ToString();
                s.Value = i.Value.ToString();
                s.IsSelectable = true;
                sl.Add(s);
            }
    
            _items = sl;
        }
    
        private ObservableCollection<SortList> _items = new ObservableCollection<SortList>();
        public ObservableCollection<SortList> Items
        {
            get
            {
                return _items;
            }
        }
    
        private SortList _selectedSort;
        public event PropertyChangedEventHandler PropertyChanged;
        public SortList SelectedItem
        {
            get { return _selectedSort; }
            set
            {
                if (_selectedSort != value)
                {
                    _selectedSort = value;
                    _selectedSort.IsSelectable = false;
                    PropertyChanged(this, new PropertyChangedEventArgs("SelectedItem"));
                }
            }
        }
    }
    

    【讨论】:

    • 非常感谢!我很想赞成你的回答,但我没有足够的声誉......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-13
    • 1970-01-01
    • 2011-07-07
    • 2012-04-16
    • 2014-03-11
    • 2019-10-01
    • 2010-09-16
    相关资源
    最近更新 更多