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="&#xE767;"
         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这样的话,前景也会一起改变。