簡體   English   中英

UWP ListView多選與MVVM綁定 Model

[英]UWP ListView Multi-Selection binding with MVVM Model

我正在嘗試在 UWP 中實現多選列表視圖,同時盡可能接近 MVVM model。我的問題是我無法通過綁定在視圖模型中獲取所選項目。

查看關於 SO 的其他答案,我發現實現此目的的唯一可能方法是通過ListViewCommandCommandParameter字段進行綁定。 然而,答案通常要么集中在簡單的代碼隱藏方法上,要么是使用 WPF 做出的,這導致我無法執行命令。

在我的 MWE 之前的一個簡短說明:該程序將 a.pdf 文件作為輸入並通過將每個頁面轉換為BitmapImage來顯示它。 我想要的是 select 這些單頁(BitmapImages)並對所有選定項目執行操作(在本例中為不同的操作;但是,我的 MWE 僅包含一個按鈕)。 我正在嘗試在 UWP 中實現多選列表視圖,同時盡可能接近 MVVM model。我的問題是我無法通過綁定在視圖模型中獲取所選項目。

這是我的 MWE:

Model

 public class PdfPageModel
    {
        public string Title { get; set; }
        public PdfDocument PdfDoc { get; set; }

        public PdfPageModel(string Title, PdfDocument pdfdoc)
        {
            this.Title = Title;
            this.PdfDoc = pdfdoc;
        }

看法

<ListView
                x:Name="PdfPageViewer"
                CanReorderItems="True" AllowDrop="True" CanDragItems="True"
                ItemsSource="{x:Bind ViewModel.PdfPages}"
                IsItemClickEnabled="True"
                SelectionMode="Multiple"
                
                IsMultiSelectCheckBoxEnabled="False"
                ScrollViewer.HorizontalScrollBarVisibility="Auto"
                ScrollViewer.HorizontalScrollMode="Enabled"
                ScrollViewer.IsHorizontalRailEnabled="True"
                ScrollViewer.ZoomMode="Enabled"
                IsZoomedInView="False"
                >
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <Image Source="{Binding }"/>
                    </DataTemplate>
                </ListView.ItemTemplate>

                <ListView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel
                            Orientation="Horizontal">
                        </StackPanel>
                    </ItemsPanelTemplate>
                </ListView.ItemsPanel>
            </ListView>
<Button
                CommandParameter="{Binding SelectedItems, Mode=OneWay, ElementName=PdfPageViewer}"
                Command="{x:Bind ViewModel.SelectedPagesCommand}"
                />

視圖模型

public ObservableCollection<BitmapImage> PdfPages { get; set; }

private ICommand _selectedPagesCommand;
public ICommand SelectedPagesCommand
{
    get
    {
        if (_selectedPagesCommand == null)
        {
                _selectedPagesCommand = new RelayCommand<?>(async () =>
                {
                    // ?? 
                });
        }
        return _selectedPagesCommand;
    }
}

我終於找到了如何實現這一目標。 對於任何好奇的人,或者也在這個問題上絆倒的人,這就是我所做的。

我找到了這個線程,它幾乎解決了我試圖做的事情。

OP 實現了一個轉換器(見下文)以從列表中獲取所有選定的項目作為ListView元素。 文檔中,我了解到SelectedItems屬性的返回類型是List接口IList<> ,我在我的SelectedPagesCommand中實現了它。

然后,他們在命令調用中使用了這個轉換器。 (請注意, SelectedItems調用已被刪除,因為使用轉換器后不再需要它。這是必要且重要的步驟。)有了這個,我終於能夠在列表中獲取選定的元素。 返回的元素是System.__ComObject類型,而不是預期的類型。 不過,這很容易規避; 簡單地將類型轉換為它應該的類型(在我的例子中,它是一個簡單的BitmapImage )。

轉換器

public class ListViewSelectedItemsConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var listView = value as ListView;
        return listView.SelectedItems;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

看法

<Page.Resources>
        <helper:ListViewSelectedItemsConverter x:Key="ListViewSelectedItemsConverter"/>
    </Page.Resources>
<!-- ... -->

<ListView
                x:Name="PdfPageViewer"
                CanReorderItems="True" AllowDrop="True" CanDragItems="True"
                ItemsSource="{x:Bind ViewModel.PdfPages}"
                IsItemClickEnabled="True"
                SelectionMode="Multiple"
                
                IsMultiSelectCheckBoxEnabled="False"
                ScrollViewer.HorizontalScrollBarVisibility="Auto"
                ScrollViewer.HorizontalScrollMode="Enabled"
                ScrollViewer.IsHorizontalRailEnabled="True"
                ScrollViewer.ZoomMode="Enabled"
                IsZoomedInView="False"
                >
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <Image Source="{Binding }"/>
                    </DataTemplate>
                </ListView.ItemTemplate>

                <ListView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel
                            Orientation="Horizontal">
                        </StackPanel>
                    </ItemsPanelTemplate>
                </ListView.ItemsPanel>
            </ListView>

<Button
                CommandParameter="{Binding ElementName=PdfPageViewer, Converter={StaticResource ListViewSelectedItemsConverter}}"
                Command="{x:Bind ViewModel.SelectedPagesCommand}"
                />

視圖模型

public ObservableCollection<BitmapImage> PdfPages { get; set; }

private ObservableCollection<BitmapImage> _selectedPdfPages;
public ObservableCollection<BitmapImage> SelectedPdfPages { get; set; }

private ICommand _selectedPagesCommand;
public ICommand SelectedPagesCommand
{
    get
    {
        if (_selectedPagesCommand == null)
        {
           _selectedPagesCommand = new RelayCommand<IList<object>>(async param =>
           {
              foreach (var i in param)
               {
                   var img = i as BitmapImage;
                   SelectedPdfPages.Add(img);
                }
             }
          }
     }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM