UWP 用户控件 ConverterParameter 绑定为空

UWP User Control ConverterParameter Binding is null

我有一个 UserControl,它有一个 属性 ThemeTheme 只是 ElementThemeEnum

public sealed partial class PlaylistControl : UserControl, MediaControlListener
{
    public ElementTheme Theme { get; set; }
    public static readonly DependencyProperty ThemeProperty = DependencyProperty.Register("Theme", typeof(ElementTheme), typeof(PlaylistControl), new PropertyMetadata(null));

    ...
}

在该控件的 xaml 中,我有一个 TextBlockForegroundForeground="{x:Bind IsPlaying, Converter={StaticResource RowColorConverter}, ConverterParameter={Binding Theme}, Mode=OneWay}"

但是,转换器似乎没有得到主题。它始终为空。

class RowColorConverter : Windows.UI.Xaml.Data.IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return value.Equals(true) ? Helper.GetHighlightBrush() :
                                    parameter is ElementTheme && (ElementTheme)parameter == ElementTheme.Dark ? Helper.WhiteSmokeBrush : Helper.BlackBrush;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return null;
    }
}

怎么了?

您在创建主题时使用了 new PropertyMetadata(null)

其含义是将Theme的默认值设置为null。请尝试修改为new PropertyMetadata(ElementTheme.Light).

更新

I don't know which color to convert back when the music is not being played so I am trying this way

我尽量简化内容,假设你不需要主题资源。这是思路的解决方案:

首先在App.xaml中定义两个画笔资源,分别是未播放状态和播放状态。

<SolidColorBrush x:Key="UnplayForeground" Color="White"/>
<SolidColorBrush x:Key="PlayingForeground" Color="Red"/>

写一个方法从当前Resource资源中获取指定名称的资源:

public static Brush GetResourceBrush(string key)
{
    return (Brush)Application.Current.Resources[key];
}

然后直接用IsPlaying转属性.

public class RowColorConverter:IValueConverter
{
    if(value is bool isPlaying)
    {
        return isPlaying ? GetResourceBrush("PlayingForeground") : 
                           GetResourceBrush("UnplayForeground");
    }
    return GetResourceBrush("UnplayForeground");
}

更新2

But how is your key different from my Theme?

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.ThemeDictionaries>
            <ResourceDictionary x:Key="Light">
                <SolidColorBrush x:Key="PlayingForeground" Color="Green"/>
                <SolidColorBrush x:Key="UnplayForeground" Color="Black"/>
            </ResourceDictionary>
            <ResourceDictionary x:Key="Dark">
                <SolidColorBrush x:Key="PlayingForeground" Color="Red"/>
                <SolidColorBrush x:Key="UnplayForeground" Color="White"/>
            </ResourceDictionary>
        </ResourceDictionary.ThemeDictionaries>
    </ResourceDictionary>
</Application.Resources>

主题切换需要创建两个资源字典,分别命名为Light和Dark。在这两个资源字典中,有同名的资源。

当需要更换主题时,应该修改Control的RequestedTheme 属性而不是新建Theme 属性.

切换主题时,软件也会切换对应的ResourceDictionary,资源名称不变。这就是为什么GetResourceBrush(string key)总是根据key获取当前主题资源的原因。

此致。

感谢理查德回答我的问题。正如他所说,我无法将绑定的主题传递给 ConverterParameter。所以没有办法使用 ConverterParameter.

来解决我的问题

我发布答案的原因是我只是想展示解决问题的方法。

由于我同时显示的只有一个PlaylistControl,我可以再声明一个静态变量UITheme CurrentTheme。当控件为Loaded时,将其成员变量Theme赋值给CurrentTheme,我就可以在转换器中轻松切换颜色了:

public object Convert(object value, Type targetType, object parameter, string language)
{
    return value.Equals(true) ? Helper.GetHighlightBrush() :
                                CurrentTheme == ElementTheme.Dark ? Helper.WhiteSmokeBrush : Helper.BlackBrush;
}