好吧,我想在UWP中创建ListViewItem,这将改变他对选择的看法.所以我需要在选择时更改ListViewItem的某些元素的Visibility属性.
我找到了一些方法来做这个与ListViewItem的自定义Style和这样的Binding 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属性?
最佳答案 我不建议更改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;
}