使用WinUI3和XAML数据绑定,当源包含索引操作并且是子字段时,如何获取要更新的字段?

问题描述 投票:0回答:1

我有一个名为 PlayerState 的状态类,其中包含许多我想通过 XAML 绑定的字段,因此我需要一个可扩展的解决方案。

我在 ViewModel 中包含此代码,该代码继承自 Microsoft 提供的 BindableBase 类,以便在调用 SetProperty 时触发绑定。我已验证使用正确的数据调用 SetProperty。

    private PlayerState _playerState;
    public PlayerState PlayerState
    {
        get { return _playerState; }
        set { SetProperty(ref _playerState, value); }
    }

    internal void OnStateChange(PlayerState playerState)
    {
        PlayerState = playerState;
    }

我有这个绑定,其中包含上述 ViewModel 的上下文,并且不知道应该如何调试 XAML。我得到的错误是

'Active' property not found on 'App.Models.PlayerState'
。 PlayerState 中的所有字段都是公共且只读的。

    <Image
        x:Name="ActiveImage"
        Source="{Binding PlayerState.Active.ImageFileNames[ImageSize.SMALL], Mode=OneWay, FallbackValue=/Assets/BlankCard2.png}"
        Margin="5"
        Grid.Row="0"
        Grid.Column="5" />

我在文件后面的代码中设置了上下文。

    public PlayerPage()
    {
        InitializeComponent();
        DataContext = ViewModel;
    }

但是当 PlayerState 的 Active 字段更改并且 PlayerState 更新时,绑定不会更新图像。为什么? 路径

Active.ImageFileNames[ImageSize.SMALL]
是正确的,因为当我将它们绑定到 ListView 时它可以工作。

我会使用

bind
,但它不支持索引,所以这里可能有什么问题?

c# xaml data-binding winui-3 winui
1个回答
0
投票

我假设

ImageSize
是一个
enum
,像这样:

public enum ImageSize
{
    SMALL,
    MEDIUM,
    LARGE,
}

但是 IIRC,绑定不适用于以

Dictionary
作为键的
enum
。在这种情况下,
Dictionary<ImageSize, string>

因此,一种解决方法应该是使用

Dictionary<string, string>

另一种解决方法可能是创建一个值转换器:

public class TestConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value is IDictionary<ImageSize, string> dictionary &&
            parameter is string parameterString &&
            Enum.TryParse(parameterString, out ImageSize imageSize) is true)
        {
            if (dictionary.TryGetValue(imageSize, out var fileName))
            {
                return fileName;
            }
        }

        throw new ArgumentException($"Failed to convert to file name. [value: {value} / parameter: {parameter}]");
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

并像这样使用它:

<Image Source="{Binding PlayerState.Active.ImageFileNames, Mode=OneWay, Converter={StaticResource TestConverter}, ConverterParameter='SMALL'}" />
© www.soinside.com 2019 - 2024. All rights reserved.