好吧,我想在UWP中制作ListViewItem
,这将改变他对选择的看法。所以我需要在选择时更改Visibility
的某些元素的ListViewItem
属性。
我找到了一些方法来制作自定义样式的ListViewItem
和绑定IsSelected
属性,如下所示:
<Style x:Key="VehicleListViewItemStyle" TargetType="ListViewItem" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Grid Background="Gray" Margin="1">
<Border Margin="2" Padding="10" Background="Gray" >
<StackPanel>
<ContentPresenter x:Name="Presenter1" />
<StackPanel Orientation="Horizontal" Background="Transparent" Margin="-10,0,-9,-9" VerticalAlignment="Center" x:Name="infoPanel"
Visibility="{Binding IsSelected, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}}">
<TextBlock Text="{Binding DeviceID}/> </StackPanel>
</StackPanel>
</Border>
<Border BorderThickness="1" BorderBrush="Orange" Visibility="{Binding IsSelected, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
它运作良好,但通过这种方式我无法绑定DeviceID
文本。
另一种方法是像这样创建DataTemplate
:
<DataTemplate x:Key="monitoringListViewItem" x:Name="item">
<Grid Background="Gray" Margin="1" Width="300" >
<StackPanel>
<ContentPresenter x:Name="Presenter"/>
<StackPanel Orientation="Horizontal">
<Image Source="/Assets/14th_crane_stop.png" Height="50" Width="50" Stretch="Uniform"/>
<StackPanel Orientation="Vertical" Margin="25,0,0,0 "
Visibility="{Binding IsSelected, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}}"
>
<TextBlock Text="{Binding DeviceID}" Style="{StaticResource VehicleTextStyle}"/>
<TextBlock Text="{Binding Mark}" Style="{StaticResource VehicleTextStyle}"/>
</StackPanel>
</StackPanel>
</StackPanel >
</Grid>
</DataTemplate>
现在我可以正确绑定文本,但无法绑定IsSelected
属性。我尝试使用不同的模式执行此操作,但它仍然无法正常工作,因为我无法使用DataTemplate中的TemplatedParent
键。
所以我需要一些答案:
- 我可以用第一种方式绑定文本,我该怎么做?
- 我可以用第二种方式绑定IsSelected
属性吗?
答案 0 :(得分:2)
我不建议更改ListViewItem模板,因为它会丢失它提供的所有铃声和哨声(选择外观,检查能力等)。
在第二个代码段中使用Mode=TemplatedParent
将不起作用,因为来自该上下文的模板化父级是ListViewItemPresenter,而不是ListViewItem(它是演示者的父级)。
看起来你要做的就是在选择列表项时显示其他信息。
C#类
public class NotifyPropertyChangedBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetProperty<T>(ref T property, T value, [CallerMemberName] string propertyName = "")
{
if (EqualityComparer<T>.Default.Equals(property, value))
{
return false;
}
property = value;
OnPropertyChanged(propertyName);
return true;
}
}
public class Item : NotifyPropertyChangedBase
{
private string text;
public string Text
{
get { return text; }
set { SetProperty(ref text, value); }
}
private bool isSelected;
public bool IsSelected
{
get { return isSelected; }
set { SetProperty(ref isSelected, value); }
}
}
public class MainPageViewModel : NotifyPropertyChangedBase
{
public List<Item> Items { get; set; }
private Item selectedItem;
public Item SelectedItem
{
get { return selectedItem; }
set
{
if (selectedItem != value)
{
if (selectedItem != null)
{
selectedItem.IsSelected = false;
}
SetProperty(ref selectedItem, value);
if (selectedItem != null)
{
selectedItem.IsSelected = true;
}
}
}
}
public MainPageViewModel()
{
Items = new List<Item>()
{
new Item() { Text = "Apple" },
new Item() { Text = "Banana" },
};
}
}
<强> MainPage.xaml中强>
<ListView ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Item">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Text}"/>
<!-- x:Bind doesn't require visibility converter if min SDK is targeting Anniversary update -->
<TextBlock Text="I'm selected!" Grid.Column="1" Visibility="{x:Bind IsSelected, Mode=OneWay}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<强> MainPage.xaml.cs中强>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
DataContext = new MainPageViewModel();
}
}
与单一选择相同,但有以下更改:
<强> MainPageViewModel 强>
public class MainPageViewModel : NotifyPropertyChangedBase
{
public List<Item> Items { get; set; }
public MainPageViewModel()
{
Items = new List<Item>()
{
new Item() { Text = "Apple" },
new Item() { Text = "Banana" },
};
}
public void SelectionChanged(object sender, SelectionChangedEventArgs e)
{
foreach (Item item in e.RemovedItems)
{
item.IsSelected = false;
}
foreach (Item item in e.AddedItems)
{
item.IsSelected = true;
}
}
}
<强> MainPage.xaml中强>
<ListView ItemsSource="{Binding Items}" SelectionChanged="{x:Bind ViewModel.SelectionChanged}" SelectionMode="Extended">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Item">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Text}"/>
<TextBlock Text="I'm selected!" Grid.Column="1" Visibility="{x:Bind IsSelected, Mode=OneWay}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<强> MainPage.xaml.cs中强>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
DataContext = new MainPageViewModel();
}
public MainPageViewModel ViewModel => (MainPageViewModel)DataContext;
}
答案 1 :(得分:0)
要回答该主题中的实际问题:是,可以很容易地绑定ListViewItem.IsSelected。确保您的DataTemplate内容包装在ListViewItem中。
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:MyItemViewModel">
<ListViewItem IsSelected="{Binding IsSelected, Mode=TwoWay}">
<Grid>
// template content
</Grid>
</ListViewItem>
</DataTemplate>
</ListView.ItemTemplate>
请注意,这里有许多有关WPF的问答,说这是行不通的。它确实适用于UWP(至少从SDK 10.0.19041开始)。 WPF的答案建议将其绑定在ItemsPanelTemplate或ResourceDictionary中。由于某些原因,这在UWP中不起作用。