如何正确管理BitmapImage的数据绑定和序列化/反序列化?

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

这是我的基本代码:

public class MyObject
{
    public decimal MyDeciaml { get; set; }
    public string? MyImageBase64
    {
        get
        {
            if (MyImageBase64 != null)
            {
                byte[] imageBytes = Convert.FromBase64String(MyImageBase64);
                using (MemoryStream stream = new MemoryStream(imageBytes))
                {
                    BitmapImage bitmapImage = new BitmapImage();
                    bitmapImage.BeginInit();
                    bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                    bitmapImage.StreamSource = stream;
                    bitmapImage.EndInit();
                    bitmapImage.Freeze();
                    MyImageBitmap = bitmapImage;
                }
            }

            return MyImageBase64;
        }
        set { }
    }
    [JsonIgnore]
    public BitmapImage? MyImageBitmap { get; set; }
}

我使用

ViewModelData
类和
ObservableCollection<MyObject> myObjects = new ObservableCollection<MyObject>();
与 ListBox 绑定:

<ListBox ItemsSource="{Binding MyObjects}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <Grid>
                    <Image x:Name="myImage"
                           Source="{Binding MyImageBitmap}"
                           VerticalAlignment="Center"
                           HorizontalAlignment="Center"
                           Width="Auto"
                           Height="Auto" />
                </Grid>
                <TextBlock Text="{Binding MyDeciaml }" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

它似乎在装订上效果很好。现在,当我使用

Newtonsoft.Json
JsonConvert.SerializeObject(data)
在 json 上序列化它时,我在 json 上看到了这个:

"MyImageBitmap": "System.Windows.Media.Imaging.BitmapImage"

如何删除它?好像

[JsonIgnore]
没有效果?

我想删除并保留 MyImageBase64 (在反序列化时,将其转换为

BitmapImage
,然后取回图像)。

感谢您对此的任何提示。如果可能的话,也许更好的方法是直接绑定base64字符串并转换为ListBox上的BitmapImage?

c# json wpf json-serialization
1个回答
0
投票

您的代码根本无法工作。对

MyImageBase64
属性的赋值无效,因为属性设置器为空。

您可以像下面这样编写,其中 BitmapImage 仅在(只读)

MyImageBitmap
属性的 getter 被实际访问时创建。

public class MyObject
{
    private string myImageBase64;
    private BitmapImage myBitmapImage;

    public string MyImageBase64
    {
        get { return myImageBase64; }
        set
        {
            myImageBase64 = value;
            myBitmapImage = null; // reset
        }
    }

    public BitmapImage MyImageBitmap
    {
        get
        {
            if (myBitmapImage == null && myImageBase64 != null)
            {
                byte[] imageBytes = Convert.FromBase64String(myImageBase64);

                using (MemoryStream stream = new MemoryStream(imageBytes))
                {
                    myBitmapImage = new BitmapImage();
                    myBitmapImage.BeginInit();
                    myBitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                    myBitmapImage.StreamSource = stream;
                    myBitmapImage.EndInit();
                    myBitmapImage.Freeze();
                }
            }

            return myBitmapImage;
        }
    }
}

除此之外,还不清楚为什么

JsonIgnore
属性在您的情况下不起作用。不过,您可以完全省略
MyImageBitmap
并在绑定转换器中创建位图图像。

转换器的实现可以像这样:

public class Base64ToBimapImageConverter : IValueConverter
{
    public object Convert(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        var imageBytes = System.Convert.FromBase64String(value.ToString());

        using (var stream = new MemoryStream(imageBytes))
        {
            var bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.StreamSource = stream;
            bitmapImage.EndInit();
            bitmapImage.Freeze();
            return bitmapImage;
        }
    }

    public object ConvertBack(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

在 XAML 中,它通常被声明为资源:

<Window.Resources>
    ...
    <local:Base64ToBimapImageConverter x:Key="Base64ToBimapImageConverter"/>
</Window.Resources>

并在这样的绑定中使用:

<Image Source="{Binding MyImageBase64,
                Converter={StaticResource Base64ToBimapImageConverter}}" .../>
© www.soinside.com 2019 - 2024. All rights reserved.