【问题标题】:Binding IsSelected on ListViewItem not working for me in UWP applicationListViewItem 上的绑定 IsSelected 在 UWP 应用程序中对我不起作用
【发布时间】:2021-04-01 09:01:24
【问题描述】:

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

我似乎无法让绑定工作。如果Selected = TrueSelected 上的设置在检查项目时永远不会被触发,则ListView 中的复选框不会被检查。

SettingsPage.xaml

<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 属性。

public class Column : BindableBase, INotifyPropertyChanged
{
    public string name { get; set; }
    public ColumnValidation ColumnValidation { get; set; }
    public List<RefEntryValue> LookupValues { get; set; } = null;

    private bool _selected = false;

    public bool Selected {
        get => _selected;

        set
        {
            _selected = value;

            OnPropertyChanged();
        }
    }
}

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

【问题讨论】:

    标签: xaml listview uwp listviewitem


    【解决方案1】:

    当您设置 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,0,0"
                            VerticalAlignment="Center"
                            HorizontalAlignment="Left"
                            Visibility="Collapsed">
                    <Border.Clip>
                        <RectangleGeometry Rect="0,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,0,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组成的。

    如果你想解决这个问题,我建议你可以将 CheckBox 添加到 DataTemplate。通过这样做,我们可以将“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>
    

    【讨论】:

    • 这确实是答案。 SettingsPage.xaml
    【解决方案2】:

    这就是它最终的样子。这对其他人来说似乎很笨拙吗?如果 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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-28
      • 2011-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多