在 UWP 应用程序中,ListViewItem 上的绑定 IsSelected 对我不起作用

问题描述

我正在处理具有 Selected 属性的对象列表,并尝试在多选 {{ 中将其绑定到 IsSelected 上的 ListViewItem 属性1}} UWP 中的控件。

我似乎无法让绑定生效。如果在检查项目时从未触发 ListViewListView 上的设置,则 Selected = True 中的复选框不会呈现选中状态。

enter image description here

设置页面.xaml

Selected

<Page.Resources> <DataTemplate x:Key="PreviewColumnTemplate" x:DataType="models:Column"> <TextBlock> <Run Text="{x:Bind name}"/> <Run Text=" ("/> <Run Text="{x:Bind ColumnValidation.column_label}"/> <Run Text=") "/> </TextBlock> </DataTemplate> <Style x:Key="previewColumnListViewItem" targettype="ListViewItem"> </Style> </Page.Resources> <ListView x:Name="previewColumnListView" ItemsSource="{x:Bind viewmodel.CurrentDrillHole.Collar.Columns,Mode=TwoWay}" ItemTemplate="{StaticResource PreviewColumnTemplate}" Height="400" SelectionMode="Multiple" SelectionChanged="previewColumnListView_SelectionChanged"> <ListView.Resources> <Style targettype="ListViewItem" BasedOn="{StaticResource previewColumnListViewItem}"> <Setter Property="IsSelected" Value="{Binding Selected,Mode=TwoWay}"/> </Style> </ListView.Resources> </ListView> 对象属于 viewmodel.CurrentDrillHole.Collar 类型,如下所示:

Table

public class Table : BindableBase { public string Name { get; set; } public TableValidation TableValidation { get; set; } public List<Column> Columns { get; set; } public List<Row> Rows { get; set; } = new List<Row>(); } 对象看起来像这样。在这里我想绑定到 Column 属性

Selected

我可以尝试的任何想法都将不胜感激。感谢您的帮助!

解决方法

当您设置 SelectionMode="Multiple" 时,ListViewItem 使用默认的 ListViewItemTemplate,其键为“ListViewItemExpanded”。

其样式如下:

 <Style TargetType="ListViewItem" x:Key="ListViewItemExpanded">
    ......
    <ControlTemplate TargetType="ListViewItem">
        <Grid x:Name="ContentBorder"
          Control.IsTemplateFocusTarget="True"
          FocusVisualMargin="{TemplateBinding FocusVisualMargin}"
          Background="{TemplateBinding Background}"
          BorderBrush="{TemplateBinding BorderBrush}"
          BorderThickness="{TemplateBinding BorderThickness}"
          CornerRadius="{TemplateBinding CornerRadius}"
          RenderTransformOrigin="0.5,0.5">
            ……
            <Border x:Name="MultiSelectSquare"
                        BorderBrush="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
                        BorderThickness="2"
                        Width="20"
                        Height="20"
                        Margin="12,0"
                        VerticalAlignment="Center"
                        HorizontalAlignment="Left"
                        Visibility="Collapsed">
                <Border.Clip>
                    <RectangleGeometry Rect="0,20,20">
                        <RectangleGeometry.Transform>
                            <TranslateTransform x:Name="MultiSelectClipTransform" />
                        </RectangleGeometry.Transform>
                    </RectangleGeometry>
                </Border.Clip>
                <Border.RenderTransform>
                    <TranslateTransform x:Name="MultiSelectCheckBoxTransform" />
                </Border.RenderTransform>
                <FontIcon x:Name="MultiSelectCheck"
                            FontFamily="{ThemeResource SymbolThemeFontFamily}"
                            Glyph="&#xE73E;"
                            FontSize="16"
                            Foreground="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
                            Visibility="Collapsed"
                            Opacity="0" />
            </Border>
            <Border x:Name="MultiArrangeOverlayTextBorder"
                        Opacity="0"
                        IsHitTestVisible="False"
                        Margin="12,0"
                        MinWidth="20"
                        Height="20"
                        VerticalAlignment="Center"
                        HorizontalAlignment="Left"
                        Background="{ThemeResource SystemControlBackgroundAccentBrush}"
                        BorderThickness="2"
                        BorderBrush="{ThemeResource SystemControlBackgroundChromeWhiteBrush}">
                <TextBlock x:Name="MultiArrangeOverlayText"
              Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=TemplateSettings.DragItemsCount}"
              Style="{ThemeResource CaptionTextBlockStyle}"
              IsHitTestVisible="False"
              Opacity="0"
              VerticalAlignment="Center"
              HorizontalAlignment="Center"
              AutomationProperties.AccessibilityView="Raw" />
            </Border>

        </Grid>

    </ControlTemplate>
    </Setter.Value>
</Style>

如您所见,其样式中没有 CheckBox,它由 Border 和 FontIcon 组成。

如果你想解决这个问题,我建议你可以在DataTemplate中添加CheckBox。通过这样做,我们可以将“Selected”绑定到 CheckBox 的“IsChecked”属性。 请参考以下代码。

<ListView
x:Name="previewColumnListView"
ItemsSource="{x:Bind ViewModel.CurrentDrillHole.Collar.Columns,Mode=TwoWay}"   
Height="400"
SelectionChanged="previewColumnListView_SelectionChanged">
    <ListView.ItemTemplate>
        <DataTemplate x:Key="PreviewColumnTemplate" x:DataType="models:Column">
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="{Binding Selected,Mode=TwoWay}"/>
                <TextBlock>
          <Run Text="{x:Bind name}"/>
          <Run Text=" ("/>
          <Run Text="{x:Bind ColumnValidation.column_label}"/>
          <Run Text=") "/>
                </TextBlock>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>
,

这就是它最后的样子。这对其他人来说看起来很笨拙吗?如果 ListView 控件能够更轻松地处理集合和 SelectionMode="Multiple",那就太好了。

SettingsPage.xaml

<ListView
    x:Name="previewColumnListView"
    ItemsSource="{x:Bind ViewModel.CurrentDrillHole.Collar.Columns,Mode=TwoWay}"
    Height="400"
    SelectionChanged="previewColumnListView_SelectionChanged"
    IsItemClickEnabled="True"
    ItemClick="previewColumnListView_ItemClick">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="models:Column">
            <StackPanel Orientation="Horizontal">
                <CheckBox Click="previewColumnListView_CheckBox_Click" IsChecked="{Binding Selected,Mode=TwoWay}"/>
                <TextBlock>
                  <Run Text="{x:Bind name}"/>
                  <Run Text=" ("/>
                  <Run Text="{x:Bind ColumnValidation.column_label}"/>
                  <Run Text=") "/>
                </TextBlock>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

SettingsPage.xaml.cs

private async void previewColumnListView_CheckBox_Click(object sender,RoutedEventArgs e)
{
    // update the list of selected columns
    Settings.CollarPreviewFields = ViewModel.CurrentDrillHole.Collar.Columns.Where(x => x.Selected).Select(x => x.name).ToList();

    await App.SaveSettings();
}

private void previewColumnListView_ItemClick(object sender,ItemClickEventArgs e)
{
    Column selectedColumn = (Column)e.ClickedItem;

    selectedColumn.Selected = !selectedColumn.Selected;

    // trigger checkbox click event. will update the list and save.
    previewColumnListView_CheckBox_Click(null,null);
}

enter image description here