Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 防止列表框选择_C#_Wpf_Mvvm_Listbox - Fatal编程技术网

C# 防止列表框选择

C# 防止列表框选择,c#,wpf,mvvm,listbox,C#,Wpf,Mvvm,Listbox,我有一个多选列表框,其中只允许选择某些项目的组合。 我怎么能拒绝某些选择? 列表框绑定到视图模型。我以为我可以在属性设置器中完成,但它不起作用 XAML 编辑: 我应该说清楚,我使用的是多重选择。这就是为什么我使用交互触发器,而不仅仅是绑定到SelectedItem。链接答案用于单选。我发现最简单的方法是不使用SelectionMode或SelectedItem,而是使用点击事件。从中您可以获得“所选项目” 然后,我在ViewModel中设置了一个绑定属性,视图使用该属性更改ListView中所

我有一个多选列表框,其中只允许选择某些项目的组合。 我怎么能拒绝某些选择? 列表框绑定到视图模型。我以为我可以在属性设置器中完成,但它不起作用

XAML

编辑:
我应该说清楚,我使用的是多重选择。这就是为什么我使用交互触发器,而不仅仅是绑定到SelectedItem。链接答案用于单选。

我发现最简单的方法是不使用SelectionMode或SelectedItem,而是使用点击事件。从中您可以获得“所选项目”

然后,我在ViewModel中设置了一个绑定属性,视图使用该属性更改ListView中所选项目的背景(如果我要选择该项目)。要有效地做到这一点,ListView需要绑定到ViewModels的ObservableCollection(或实现INotifyPropertyChanged的类)

下面是一些粗略的代码来说明我的意思: 在Xaml视图代码中

<ListView 
    ItemsSource ="{Binding Values}"
    ItemTapped="OnItemTapped"
    HasUnevenRows="True"
    RefreshAllowed="True"
    SelectionMode="None"
    >
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <Grid  RowSpacing="0" >
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="100*"/>
                        <ColumnDefinition Width="40"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="30*"/>
                    </Grid.RowDefinitions>
                    <BoxView Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" BackgroundColor="{StaticResource Blue}" IsVisible="{Binding IsSelected}" />
                    <Label   Grid.Column="0" Grid.Row="0" HorizontalTextAlignment="Center" VerticalOptions="Center" Text="{Binding Destination}"/>
                    <Label   Grid.Column="1" Grid.Row="0" HorizontalTextAlignment="Start" VerticalOptions="Center" Text="{Binding Value}"/>
                </Grid>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>
然后使用这些类-第一个是视图的BindingContext

public class SourceViewModel:INotifyPropertyChanged
{
    public SourceViewModel (List<ValueViewModel> list)
    {
        SelectValueCommand = new Command<ValueViewModel>((value) => ExecuteSelectValueCommand(value), (value)=>!IsBusy);
    }

    private ObservableCollection<ValueViewModel> _values = new ObservableCollection<ValueViewModel>();
    private bool _isSelected;
    private sring _description;

    public ICommand SelectValueCommand;
    public bool IsBusy{get;set;}

    public ObservableCollection<ValueViewModel> Values 
    {
        get=>_values;
        set
        {
            _values = value;
            OnPropertyChanged(nameof(Values));
        }
    }

    public void ExecuteSelectValueCommand(ValueViewModel value)
    {
        if(IsBusy) return;

        item.IsSelected = CanValueBeSelected(value);        
    }

    private bool CanValueBeSelected(ValueViewModel value)
    {
        var result = false;

        //Some logic to determine if it can be selected

        return result;
    }
    #region INotifyPropertyChanged implementation
    // ...
    #endregion  
}


public class ValueViewModel:INotifyPropertyChanged
{
    public ValueViewModel (string description, int value)
    {
        Description = description;
        Value = value;
    }

    private int _value;
    private bool _isSelected;
    private sring _description;

    public int Value
    {
        get=>_value;
        set
        {
            _value=value;
            OnPropertyChanged(nameof(Value));
        }
    }

    public bool IsSelected
    {
        get=> _isSelected;
        set
        {
            _isSelected= value;
            OnPropertyChanged(nameof(IsSelected));
        }
    }

    public string Description
    {
        get=> _description;
        set
        {
            _description= value;
            OnPropertyChanged(nameof(Description));
        }
    }
    #region INotifyPropertyChanged implementation
    // ...
    #endregion  
}
公共类SourceViewModel:INotifyPropertyChanged
{
公共源视图模型(列表)
{
SelectValueCommand=new命令((值)=>ExecuteSelectValueCommand(值),(值)=>!IsBusy);
}
私有ObservableCollection_值=新ObservableCollection();
私立学校当选;
私有sring_描述;
public-ICommand和SelectValueCommand;
公共bool正忙{get;set;}
公共可观测收集值
{
获取=>\u值;
设置
{
_价值=价值;
OnPropertyChanged(名称(值));
}
}
public void ExecuteSelectValueCommand(ValueViewModel值)
{
如果(忙)返回;
item.IsSelected=CanValueBeSelected(值);
}
私有布尔值可选择(ValueViewModel值)
{
var结果=假;
//确定是否可以选择的一些逻辑
返回结果;
}
#区域INotifyPropertyChanged实现
// ...
#端区
}
公共类ValueViewModel:INotifyPropertyChanged
{
public ValueViewModel(字符串描述,int值)
{
描述=描述;
价值=价值;
}
私有整数值;
私立学校当选;
私有sring_描述;
公共整数值
{
获取=>\u值;
设置
{
_价值=价值;
OnPropertyChanged(名称(值));
}
}
公选学校
{
get=>\u被选中;
设置
{
_isSelected=值;
OnPropertyChanged(名称(IsSelected));
}
}
公共字符串描述
{
获取=>\u描述;
设置
{
_描述=值;
OnPropertyChanged(名称(描述));
}
}
#区域INotifyPropertyChanged实现
// ...
#端区
}

这是否回答了您的问题?问题是我有一个多重选择列表框,无法确定如何修改答案,这是针对单一选择的。我想我将在用户提交对话框时验证选择。
<ListView 
    ItemsSource ="{Binding Values}"
    ItemTapped="OnItemTapped"
    HasUnevenRows="True"
    RefreshAllowed="True"
    SelectionMode="None"
    >
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <Grid  RowSpacing="0" >
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="100*"/>
                        <ColumnDefinition Width="40"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="30*"/>
                    </Grid.RowDefinitions>
                    <BoxView Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" BackgroundColor="{StaticResource Blue}" IsVisible="{Binding IsSelected}" />
                    <Label   Grid.Column="0" Grid.Row="0" HorizontalTextAlignment="Center" VerticalOptions="Center" Text="{Binding Destination}"/>
                    <Label   Grid.Column="1" Grid.Row="0" HorizontalTextAlignment="Start" VerticalOptions="Center" Text="{Binding Value}"/>
                </Grid>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>
private void OnItemTapped(object sender, ItemTappedEventArgs e)
{
    var param = (ValueViewModel)e.Item;
    if (((SourceViewModel)BindingContext).SelectValueCommand.CanExecute(param))
    {
        ((SourceViewModel)BindingContext).SelectValueCommand.Execute(param);
    }
}
public class SourceViewModel:INotifyPropertyChanged
{
    public SourceViewModel (List<ValueViewModel> list)
    {
        SelectValueCommand = new Command<ValueViewModel>((value) => ExecuteSelectValueCommand(value), (value)=>!IsBusy);
    }

    private ObservableCollection<ValueViewModel> _values = new ObservableCollection<ValueViewModel>();
    private bool _isSelected;
    private sring _description;

    public ICommand SelectValueCommand;
    public bool IsBusy{get;set;}

    public ObservableCollection<ValueViewModel> Values 
    {
        get=>_values;
        set
        {
            _values = value;
            OnPropertyChanged(nameof(Values));
        }
    }

    public void ExecuteSelectValueCommand(ValueViewModel value)
    {
        if(IsBusy) return;

        item.IsSelected = CanValueBeSelected(value);        
    }

    private bool CanValueBeSelected(ValueViewModel value)
    {
        var result = false;

        //Some logic to determine if it can be selected

        return result;
    }
    #region INotifyPropertyChanged implementation
    // ...
    #endregion  
}


public class ValueViewModel:INotifyPropertyChanged
{
    public ValueViewModel (string description, int value)
    {
        Description = description;
        Value = value;
    }

    private int _value;
    private bool _isSelected;
    private sring _description;

    public int Value
    {
        get=>_value;
        set
        {
            _value=value;
            OnPropertyChanged(nameof(Value));
        }
    }

    public bool IsSelected
    {
        get=> _isSelected;
        set
        {
            _isSelected= value;
            OnPropertyChanged(nameof(IsSelected));
        }
    }

    public string Description
    {
        get=> _description;
        set
        {
            _description= value;
            OnPropertyChanged(nameof(Description));
        }
    }
    #region INotifyPropertyChanged implementation
    // ...
    #endregion  
}