如何将图像绑定到 GridColumn?
How to bind image to GridColumn?
我有一个 GridColumn,FieldName==“Image”。 Image是MyClass中属性类型的BitmapImage,在构造函数中赋值
XAML:
<dxg:GridColumn Header="MyImage" ReadOnly="True" VisibleIndex="0" AllowResizing="False" Width="20*"
HorizontalHeaderContentAlignment="Center"
FieldName="Image">
<dxg:GridColumn.EditSettings>
<dxe:ImageEditSettings MaxWidth="15" />
</dxg:GridColumn.EditSettings></dxg:GridColumn>
我的班级:
public class MyClass
{
public MyClass(ImageType imageType)
{
Image = imageType switch
{
ImageType.T1=> new BitmapImage(new Uri(@"pack://application:,,,/MyProject;component/Assets/Images/information-blue-red.png", UriKind.RelativeOrAbsolute)),
ImageType.T2=> new BitmapImage(new Uri(@"pack://application:,,,/MyProject;component/Assets/Images/information-blue.png", UriKind.RelativeOrAbsolute)),
ImageType.T3=> new BitmapImage(new Uri(@"pack://application:,,,MyProject;component/Assets/Images/information-red.png", UriKind.RelativeOrAbsolute)),
ImageType.T4=> new BitmapImage(new Uri(@"pack://application:,,,/MyProject;component/Assets/Images/information-white.png", UriKind.RelativeOrAbsolute)),
_ => default
};
}
public BitmapImage Image { get; set; }
}
所以我用那种类型的 ItemsSource 填充 GridControl。当我执行程序时 - 首先调用刷新方法,一切正常,我的意思是每个单元格都包含需要的图像。但是,如果我再次刷新它(调用这种异步方法)- ItemsSource 再次被填充,并且 MyClass 对象的创建没有任何问题,但是我收到一个错误,一个对象在另一个线程中,所以它无法访问,刷新后。我不确切知道是哪个对象,但我敢肯定,它与 Image 属性 有关,因为我已经在没有此类列的情况下进行了测试,结果没问题。
错误:
System.InvalidOperationException:“调用线程无法访问此对象,因为另一个线程拥有此对象。”
您的 MyClass 构造函数似乎是在 UI 线程以外的线程中调用的。因此,它应该注意通过冻结它来使图像中的 BitmapImage 属性 跨线程可访问。
属性 也应该是只读的,或者它应该在设置时触发更改通知。
而且不需要设置 UriKind.RelativeOrAbsolute
因为 Pack URI 总是绝对的。
public MyClass(ImageType imageType)
{
var name = imageType switch
{
ImageType.T1 => "information-blue-red.png",
ImageType.T2 => "information-blue.png",
ImageType.T3 => "information-red.png",
ImageType.T4 => "information-white.png",
_ => null
};
if (name != null)
{
var uri = new Uri(
"pack://application:,,,/MyProject;component/Assets/Images/" + name);
var image = new BitmapImage(uri);
image.Freeze(); // here
Image = image;
// alternatively, call Image = BitmapFrame.Create(uri);
}
}
public ImageSource Image { get; }
我有一个 GridColumn,FieldName==“Image”。 Image是MyClass中属性类型的BitmapImage,在构造函数中赋值
XAML:
<dxg:GridColumn Header="MyImage" ReadOnly="True" VisibleIndex="0" AllowResizing="False" Width="20*"
HorizontalHeaderContentAlignment="Center"
FieldName="Image">
<dxg:GridColumn.EditSettings>
<dxe:ImageEditSettings MaxWidth="15" />
</dxg:GridColumn.EditSettings></dxg:GridColumn>
我的班级:
public class MyClass
{
public MyClass(ImageType imageType)
{
Image = imageType switch
{
ImageType.T1=> new BitmapImage(new Uri(@"pack://application:,,,/MyProject;component/Assets/Images/information-blue-red.png", UriKind.RelativeOrAbsolute)),
ImageType.T2=> new BitmapImage(new Uri(@"pack://application:,,,/MyProject;component/Assets/Images/information-blue.png", UriKind.RelativeOrAbsolute)),
ImageType.T3=> new BitmapImage(new Uri(@"pack://application:,,,MyProject;component/Assets/Images/information-red.png", UriKind.RelativeOrAbsolute)),
ImageType.T4=> new BitmapImage(new Uri(@"pack://application:,,,/MyProject;component/Assets/Images/information-white.png", UriKind.RelativeOrAbsolute)),
_ => default
};
}
public BitmapImage Image { get; set; }
}
所以我用那种类型的 ItemsSource 填充 GridControl。当我执行程序时 - 首先调用刷新方法,一切正常,我的意思是每个单元格都包含需要的图像。但是,如果我再次刷新它(调用这种异步方法)- ItemsSource 再次被填充,并且 MyClass 对象的创建没有任何问题,但是我收到一个错误,一个对象在另一个线程中,所以它无法访问,刷新后。我不确切知道是哪个对象,但我敢肯定,它与 Image 属性 有关,因为我已经在没有此类列的情况下进行了测试,结果没问题。
错误:
System.InvalidOperationException:“调用线程无法访问此对象,因为另一个线程拥有此对象。”
您的 MyClass 构造函数似乎是在 UI 线程以外的线程中调用的。因此,它应该注意通过冻结它来使图像中的 BitmapImage 属性 跨线程可访问。
属性 也应该是只读的,或者它应该在设置时触发更改通知。
而且不需要设置 UriKind.RelativeOrAbsolute
因为 Pack URI 总是绝对的。
public MyClass(ImageType imageType)
{
var name = imageType switch
{
ImageType.T1 => "information-blue-red.png",
ImageType.T2 => "information-blue.png",
ImageType.T3 => "information-red.png",
ImageType.T4 => "information-white.png",
_ => null
};
if (name != null)
{
var uri = new Uri(
"pack://application:,,,/MyProject;component/Assets/Images/" + name);
var image = new BitmapImage(uri);
image.Freeze(); // here
Image = image;
// alternatively, call Image = BitmapFrame.Create(uri);
}
}
public ImageSource Image { get; }