UWP 更改 MasterView 中 ListView DataTemplate 的样式
UWP change style of ListView DataTemplate in a MasterView
这是XAML的结构:
<controls:MasterDetailsView
ItemsSource="{x:Bind Artists}">
<controls:MasterDetailsView.MasterHeader>
// Some Code
</controls:MasterDetailsView.MasterHeader>
<controls:MasterDetailsView.ItemTemplate>
// Some Code
</controls:MasterDetailsView.ItemTemplate>
<controls:MasterDetailsView.DetailsTemplate>
<DataTemplate x:DataType="data:ArtistView">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<RelativePanel HorizontalAlignment="Stretch">
// Some Code
</RelativePanel>
<ListView
x:Name="AlbumsListView"
Grid.Row="1"
HorizontalAlignment="Stretch"
ItemsSource="{x:Bind Albums}"
SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate x:DataType="data:AlbumView">
<Grid Margin="10,0,0,30">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<RelativePanel>
// Some Code
</RelativePanel>
<ListView
x:Name="SongsListView"
Grid.Row="1"
HorizontalAlignment="Stretch"
ContainerContentChanging="SongsListView_ContainerContentChanging"
IsItemClickEnabled="True"
ItemClick="SongsListView_ItemClick"
ItemsSource="{x:Bind Songs}"
SelectionMode="Single">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Music">
// Some Code
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</DataTemplate>
</controls:MasterDetailsView.DetailsTemplate>
</controls:MasterDetailsView>
我试图通过更改前景来突出显示正在播放音乐的 SongsListView
项(它在另一个列表视图中)。我在 ContainerContentChanging 中实现了它,但只有在重新加载页面后才会更改前景。我希望它实时更新。我该怎么做?
我注册了一个MusicSwitching事件,当当前正在播放的音乐发生变化时,我可以将已经播放的项目的前景设置为黑色,将要播放的项目的前景设置为a高亮颜色。
public async void MusicSwitching(Music current, Music next)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
{
var item = ArtistMasterDetailsView.Items.First((a) => (a as ArtistView).Name == next.Artist);
var container = ArtistMasterDetailsView.ContainerFromItem(item);
});
}
我首先可以正确找到该项目,但容器为空。为什么?我以为是包含该项目的 DataTemplate。
如果你想高亮SongsListView的一个项目,简单的方法是在Music中设置一个属性(我看到你设置了一个IsPlaying方法,我把它改成了属性) class绑定到你要hightlight.About绑定的item中的控件,可以参考这个document.
首先,你应该让 Music class 继承自 INotifyPropertyChanged 来监听 属性 变化通知。
public class Music : IComparable<Music>, INotifyPropertyChanged
{
......
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public bool IsPlaying {
set {
IsMusicPlaying = value;
OnPropertyChanged();
}
get {
return IsMusicPlaying;
}
}
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
// Raise the PropertyChanged event, passing the name of the property whose value has changed.
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
然后,将 属性 绑定到要突出显示的项目中的控件。
<Page.Resources>
<local:ColorConvert x:Name="MyConvert"></local:ColorConvert>
</Page.Resources>
<FontIcon
x:Name="PlayingIcon"
Margin="0,0,16,0"
FontFamily="Segoe MDL2 Assets"
Foreground="{StaticResource SystemColorHighlightColor}"
Glyph=""
RelativePanel.AlignLeftWithPanel="True"
Visibility="{Binding Name, Converter={StaticResource MusicVisibilityConverter}}" />
<TextBlock
x:Name="MusicNameTextBlcok"
Grid.Column="1"
Width="720"
Text="{x:Bind Name}"
Foreground="{x:Bind IsPlaying,Converter={StaticResource MyConvert},Mode=OneWay}"/>
.cs
public class ColorConvert : IValueConverter
{
// this does not include sublevel menus right now
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value.ToString() == "False")
{
return Helper.BlackBrush;
}
else
{
return Helper.GetHighlightBrush();
}
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
最后,当MusicSwitching被触发时,可以重新设置IsPlayingproperty.In这样的话,前景也会一起改变。
这是XAML的结构:
<controls:MasterDetailsView
ItemsSource="{x:Bind Artists}">
<controls:MasterDetailsView.MasterHeader>
// Some Code
</controls:MasterDetailsView.MasterHeader>
<controls:MasterDetailsView.ItemTemplate>
// Some Code
</controls:MasterDetailsView.ItemTemplate>
<controls:MasterDetailsView.DetailsTemplate>
<DataTemplate x:DataType="data:ArtistView">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<RelativePanel HorizontalAlignment="Stretch">
// Some Code
</RelativePanel>
<ListView
x:Name="AlbumsListView"
Grid.Row="1"
HorizontalAlignment="Stretch"
ItemsSource="{x:Bind Albums}"
SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate x:DataType="data:AlbumView">
<Grid Margin="10,0,0,30">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<RelativePanel>
// Some Code
</RelativePanel>
<ListView
x:Name="SongsListView"
Grid.Row="1"
HorizontalAlignment="Stretch"
ContainerContentChanging="SongsListView_ContainerContentChanging"
IsItemClickEnabled="True"
ItemClick="SongsListView_ItemClick"
ItemsSource="{x:Bind Songs}"
SelectionMode="Single">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Music">
// Some Code
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</DataTemplate>
</controls:MasterDetailsView.DetailsTemplate>
</controls:MasterDetailsView>
我试图通过更改前景来突出显示正在播放音乐的 SongsListView
项(它在另一个列表视图中)。我在 ContainerContentChanging 中实现了它,但只有在重新加载页面后才会更改前景。我希望它实时更新。我该怎么做?
我注册了一个MusicSwitching事件,当当前正在播放的音乐发生变化时,我可以将已经播放的项目的前景设置为黑色,将要播放的项目的前景设置为a高亮颜色。
public async void MusicSwitching(Music current, Music next)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
{
var item = ArtistMasterDetailsView.Items.First((a) => (a as ArtistView).Name == next.Artist);
var container = ArtistMasterDetailsView.ContainerFromItem(item);
});
}
我首先可以正确找到该项目,但容器为空。为什么?我以为是包含该项目的 DataTemplate。
如果你想高亮SongsListView的一个项目,简单的方法是在Music中设置一个属性(我看到你设置了一个IsPlaying方法,我把它改成了属性) class绑定到你要hightlight.About绑定的item中的控件,可以参考这个document.
首先,你应该让 Music class 继承自 INotifyPropertyChanged 来监听 属性 变化通知。
public class Music : IComparable<Music>, INotifyPropertyChanged
{
......
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public bool IsPlaying {
set {
IsMusicPlaying = value;
OnPropertyChanged();
}
get {
return IsMusicPlaying;
}
}
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
// Raise the PropertyChanged event, passing the name of the property whose value has changed.
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
然后,将 属性 绑定到要突出显示的项目中的控件。
<Page.Resources>
<local:ColorConvert x:Name="MyConvert"></local:ColorConvert>
</Page.Resources>
<FontIcon
x:Name="PlayingIcon"
Margin="0,0,16,0"
FontFamily="Segoe MDL2 Assets"
Foreground="{StaticResource SystemColorHighlightColor}"
Glyph=""
RelativePanel.AlignLeftWithPanel="True"
Visibility="{Binding Name, Converter={StaticResource MusicVisibilityConverter}}" />
<TextBlock
x:Name="MusicNameTextBlcok"
Grid.Column="1"
Width="720"
Text="{x:Bind Name}"
Foreground="{x:Bind IsPlaying,Converter={StaticResource MyConvert},Mode=OneWay}"/>
.cs
public class ColorConvert : IValueConverter
{
// this does not include sublevel menus right now
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value.ToString() == "False")
{
return Helper.BlackBrush;
}
else
{
return Helper.GetHighlightBrush();
}
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
最后,当MusicSwitching被触发时,可以重新设置IsPlayingproperty.In这样的话,前景也会一起改变。