【问题标题】:Selected Items implementation in a ListBox acts odd in WPF and MVVMListBox 中的选定项实现在 WPF 和 MVVM 中表现得很奇怪
【发布时间】:2022-07-20 20:19:50
【问题描述】:

我进行了相当多的研究,以在 WPF 中通过 MVVM 实现所选项目。我以为我成功了,但现在选择是根据滚动位置进行的。我选择了列表框中的所有项目,但只有前 11 个标记为选中。如果我滚动更多,选择更多。如果我滚动到底部所有选定的项目。这个问题有解决办法吗?

XAML:

<ListBox x:Name="DataListBox" SelectionMode="Extended" HorizontalAlignment="Left" Margin="5,5,0,0" Grid.Row="1"  Grid.Column="0" Grid.RowSpan="8" 
                                 VerticalAlignment="Top" Height="200" Width="200"                                 
                                 ItemsSource="{Binding DataListBoxItemsSource, UpdateSourceTrigger=PropertyChanged}"
                                 SelectedItem="{Binding DataListBoxSelectedItem, UpdateSourceTrigger=PropertyChanged}"
                                >

                            <ListBox.InputBindings>
                                <KeyBinding Command="ApplicationCommands.SelectAll" Modifiers="Ctrl" Key="A" />
                            </ListBox.InputBindings>

                            <ListBox.ItemContainerStyle>
                                <Style TargetType="ListBoxItem">
                                    <Setter Property="IsSelected" Value="{Binding IsSelected}"/>
                                </Style>
                            </ListBox.ItemContainerStyle>

                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="SelectionChanged" >
                                    <i:CallMethodAction TargetObject="{Binding}" MethodName="DataListBox_SelectionChanged"/>
                                </i:EventTrigger>
                            </i:Interaction.Triggers>
                        </ListBox>

查看模型

        public async void CreateLayersTOC()
    {
        if (MapView.Active != null)
        {
            if (DataListBoxSelectedItem != null || FavoriteTabsSelectedItem != null)
                MainStackPanelIsEnabled = false;
            LayerNames = new List<string>();
            await Task.Run(() =>
            {
                MessageBox.Show("source count " + DataListBoxItemsSource.Count);//58 items all selected
                if (DataListBoxSelectedItem != null)
                    foreach (ItemPresenter itemP in DataListBoxItemsSource)
                    {
                        if (itemP.IsSelected)
                        {
                            if (LayerNames.Contains(itemP.ToString()) == false)
                                LayerNames.Add(itemP.ToString());
                        }

                    }

                if (FavoriteTabsSelectedItem != null)
                {
                    foreach (ItemPresenter itemP in FavListBoxItemsSource)
                    {
                        if (itemP.IsSelected)
                        {
                            if (LayerNames.Contains(itemP.ToString()) == false)
                                LayerNames.Add(itemP.ToString());
                        }
                    }
                }

                MessageBox.Show("Coll" + LayerNames.Count);//Count depends on scroll position
            });

            //do stuff
        }
        else
            MessageBox.Show("Make sure to have a map available before adding layers to a map");
        MainStackPanelIsEnabled = true;
    }

 public class ItemPresenter : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private readonly string _value;

        public ItemPresenter(string value)
        {
            _value = value;
        }

        public override string ToString()
        {
            return _value;
        }

        private bool _isSelected;

        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                if (_isSelected != value)
                {
                    _isSelected = value;
                    OnPropertyChanged();
                }
            }
        }
    }

【问题讨论】:

  • 目前还不清楚您究竟想在这里做什么。您可以将 ListBox 的 SelectedItem 属性绑定到视图模型的属性,并且在 ItemContainerStyle(ListBoxItem 样式)中,您可以绑定项目的 IsSelected 属性。不需要更多。
  • @Clemens 这就是为什么我已经这样做了。您认为代码的哪一部分是错误的/不必要的? ItemPresenter 类?我只想获取所有选定的项目并作为字符串添加到集合中。然后做一些事情。
  • 请看我回答中的例子。

标签: c# wpf mvvm selecteditem


【解决方案1】:

以下是绑定 ListBox 的 SelectedItem 和 ListBoxItems 的 IsSelected 属性所需的一切的简单示例。

XAML:

<ListBox ItemsSource="{Binding Items}" SelectionMode="Extended">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsSelected" Value="{Binding Selected}"/>
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Text}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

查看模型:

public class DataItem : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public string Text { get; set; }

    private bool selected;

    public bool Selected
    {
        get { return selected; }
        set
        {
            selected = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Selected)));
            Debug.WriteLine(Text + " selected: " + selected);
        }
    }
}

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public ObservableCollection<DataItem> Items { get; } = new ObservableCollection<DataItem>();

    private DataItem selectedData;

    public DataItem SelectedData
    {
        get { return selectedData; }
        set
        {
            selectedData = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedData)));
        }
    }
}

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        var vm = new ViewModel();
        vm.Items.Add(new DataItem { Text = "Item 1" });
        vm.Items.Add(new DataItem { Text = "Item 2" });
        vm.Items.Add(new DataItem { Text = "Item 3" });
        vm.Items.Add(new DataItem { Text = "Item 4" });
        vm.Items.Add(new DataItem { Text = "Item 5" });

        DataContext = vm;
    }
}

【讨论】:

    猜你喜欢
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-02
    • 1970-01-01
    相关资源
    最近更新 更多