【问题标题】:How to disallow the selection of an interactive ListBox item?如何禁止选择交互式 ListBox 项?
【发布时间】:2012-11-14 02:29:17
【问题描述】:

我的 ListBox 中的某些项目使用包含按钮和文本框的模板。我怎样才能使它无法从列表中选择这些项目,但仍然可以与按钮交互?

编辑:

我仍然需要能够选择此列表中的其他项目,而不是使用此模板的项目。

【问题讨论】:

    标签: c# wpf button listbox


    【解决方案1】:

    使用ItemsControl 代替列表框

    【讨论】:

    • 列表中的其他项目仍然需要可选。我已经编辑了问题以使其更加明显。
    • 我认为没有标准的方法可以做到这一点,如果您希望每个项目可选择或不可选择,则可以尝试保留每个项目的数据上下文,如果所选项目不可选择,则设置 listbox.SelectedItem = null .请让我们知道这项工作是否有效
    • 感谢您的建议。不幸的是,这对我不起作用,因为我必须检查所选项目在被选中后是否可以选择。
    【解决方案2】:

    我们可以使用 ListBoxItem 的附加属性(在我实现之后我发现了someone who had done almost the same):

    public class ListBoxItemEx
    {
        public static bool GetCanSelect(DependencyObject obj)
        {
            return (bool)obj.GetValue(CanSelectProperty);
        }
        public static void SetCanSelect(DependencyObject obj, bool value)
        {
            obj.SetValue(CanSelectProperty, value);
        }
        public static readonly DependencyProperty CanSelectProperty =
            DependencyProperty.RegisterAttached("CanSelect", typeof(bool), typeof(ListBoxItemEx), new UIPropertyMetadata(true, OnCanSelectChanged));
    
        private static void OnCanSelectChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            var item = sender as ListBoxItem;
            if (item == null)
                return;
    
            if ((bool)args.NewValue)
            {
                item.Selected -= ListBoxItemSelected;
            }
            else
            {
                item.Selected += ListBoxItemSelected;
                item.IsSelected = false;
            }
        }
    
        private static void ListBoxItemSelected(object sender, RoutedEventArgs e)
        {
            var item = sender as ListBoxItem;
            if (item == null)
                return;
            item.IsSelected = false;
        }
    }
    

    xaml:

    <Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow"
        Width="525"
        Height="350">
    <Window.Resources>
        <Style x:Key="ListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
            <Setter Property="local:ListBoxItemEx.CanSelect" Value="{Binding CanSelect}"/>
        </Style>
    </Window.Resources>     
    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>
    <Grid Name="LayoutRoot">
        <ListBox ItemsSource="{Binding Elements}" ItemContainerStyle="{DynamicResource ListBoxItemStyle}" SelectionMode="Multiple" />
    </Grid>
    

    视图模型:

    public class ViewModel : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged values
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
    
    
        public List<Dummy> Elements { get; set; }
    
        public ViewModel()
        {
            this.Elements = new List<Dummy>(){
                new Dummy() { CanSelect =true, MyProperty = "Element1"},
                new Dummy() { CanSelect =false, MyProperty = "Element2"},
                new Dummy() { CanSelect =true, MyProperty = "Element3"},
                new Dummy() { CanSelect =false, MyProperty = "Element4"},
                new Dummy() { CanSelect =true, MyProperty = "Element5"},
                new Dummy() { CanSelect =true, MyProperty = "Element6"},
                new Dummy() { CanSelect =true, MyProperty = "Element7"},
                new Dummy() { CanSelect =true, MyProperty = "Element8"},
                new Dummy() { CanSelect =false, MyProperty = "Element9"},
            };
        }
    }
    
    public class Dummy
    {
        public bool CanSelect { get; set; }
    
        public string MyProperty { get; set; }
    
        public override string ToString()
        {
            return this.MyProperty;
        }
    }
    

    这种方法的唯一注意事项是,如果 ListBox 具有单个选择项,则尝试选择不可选择的项会取消选择当前选定的项,如果 ListBox 具有扩展选择项,则取消选择所有项。

    【讨论】:

    • 非常感谢,这正是我想要的!
    猜你喜欢
    • 1970-01-01
    • 2012-08-21
    • 2021-10-24
    • 2020-01-03
    • 1970-01-01
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多