问题描述
我正在处理具有 Selected
属性的对象列表,并尝试在多选 {{ 中将其绑定到 IsSelected
上的 ListViewItem
属性1}} UWP 中的控件。
我似乎无法让绑定生效。如果在检查项目时从未触发 ListView
和 ListView
上的设置,则 Selected = True
中的复选框不会呈现选中状态。
设置页面.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=""
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);
}