c# - 列表框中部分可见的项目不会触发绑定(bind)命令

标签 c# wpf xaml listbox

在我的 XAML 中,我有一个绑定(bind)到 View 模型对象列表的 ListBox。

用户控件被定义为使用此 TestViewModel 作为其数据上下文。 在用户控件中,我有 2 个命令按钮,它们绑定(bind)到使用 ICommand 模式的方法。在这些按钮的帮助下,我能够向上述列表添加和删除 View 模型,这使得 ListBox 的高度增加(这使得滚动条出现)。

似乎一切正常。但是,当用户控件由于屏幕/应用程序高度不够而部分显示时,事情并没有按预期方式工作。

即使命令按钮可见,命令也不会被触发。取而代之的是,ListBox 滚动到最后一个项目,部分显示的项目变得完全可见。之后,该项目的命令将按预期触发。

不能为 ListBox 设置固定高度,因为应用程序必须支持不同的屏幕分辨率。

有人知道如何解决这个问题吗?或者这是预期的行为?

更新:添加示例源代码。我当前的屏幕分辨率是 1366x768。在此之下,我只能看到 2 个完整控件。第三个仅部分可见。

窗口:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:uc="clr-namespace:WpfApplication1"
        Title="MainWindow" WindowState="Maximized">
    <Window.DataContext>
        <uc:MainViewModel></uc:MainViewModel>
    </Window.DataContext>
    <Grid>
        <ListBox ItemsSource="{Binding VmList}"></ListBox>
    </Grid>
</Window>

窗口的 View 模型:

public class MainViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }


        private ObservableCollection<TestViewModel> vmList;

        public ObservableCollection<TestViewModel> VmList
        {
            get { return vmList; }
            set 
            { 
                vmList = value;
                OnPropertyChanged("VmList");
            }
        }

        public MainViewModel()
        {
            VmList = new ObservableCollection<TestViewModel>() 
            {
                new TestViewModel(1),
                new TestViewModel(2),
                new TestViewModel(3)
            };
        }    
    }

用户控制:

<UserControl x:Class="WpfApplication1.TestUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" Height="300" Width="200">    
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>  
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="85*"></ColumnDefinition>
            <ColumnDefinition Width="15*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Border BorderThickness="1" BorderBrush="Gray" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2">
        <Grid Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" HorizontalAlignment="Center" VerticalAlignment="Center">
                <Border BorderThickness="2" BorderBrush="Black">
                    <Label Content="{Binding Count}"></Label></Border>
        </Grid></Border>
        <Button Grid.Row="0" Grid.Column="1" Width="30" Height="30" Command="{Binding OnControlAdd}"
                CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=DataContext}">+</Button>
    </Grid>
</UserControl>

用户控件的 View 模型:

public class TestViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        private int count;

        public int Count
        {
            get { return count; }
            set { count = value; }
        }


        public ICommand OnControlAdd
        {
            get
            {
                return new RelayCommand(AddControl);
            }
        }

        private void AddControl(object param)
        {
            MainViewModel mainView = param as MainViewModel;

            if (null != mainView)
            {
                mainView.VmList.Add(new TestViewModel(mainView.VmList.Count + 1));
            }
        }

        public TestViewModel(int count)
        {
            Count = count;
        }
    }

数据模板:

<DataTemplate DataType="{x:Type local:TestViewModel}">        
        <local:TestUserControl></local:TestUserControl>
    </DataTemplate>

最佳答案

是的,这是预期的行为,首先 ListBoxScrollViewer 将确保当您单击项目时哪些项目内容完全可见(它会吃掉点击,所以它不会到达按钮),只有这样你才能点击项目内的按钮。

要修复它,只需禁用该行为

    <ListBox ScrollViewer.CanContentScroll="False" ... />

关于c# - 列表框中部分可见的项目不会触发绑定(bind)命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32887074/

相关文章:

c# - 在使用命名空间前缀的文档上使用 Linq to XML 时出现问题

C# & MySQL 多字段搜索

wpf - 将自定义转换器作为 VB.Net 中的资源添加到 XAML 页面中

c# - 如何在对话框中设置我的主要应用程序主题,而不是在 XAML 中显式设置它?

c# - 使用 ServiceStack 通过 Redis 管理/更新 ASP.NET 中的记录

循环内的 C# SqlConnection

c# - C# 中类与结构的 "Overhead"?

c# - WPF 可选曲线

.net - "{x:Static}"在 XAML 中是什么意思?

c# - W10 新闻应用程序如何拉伸(stretch) gridview 中的项目?