gpt4 book ai didi

c# - 虚拟化不改变新可见项目的属性

转载 作者:太空狗 更新时间:2023-10-30 01:32:48 24 4
gpt4 key购买 nike

我目前在 ListView 中使用自定义图像对象(<Image> 对象的包装器)。当新的 ListView 项目可见(实现)时,我的自定义 Image 对象的属性不会改变。

例如,如果我的 ListView (包含 30 个具有不同图像 URL 和不同文本的项目)在第一个滚动条上有 3 个项目,那么第 10 个项目与第一个项目具有相同的图像。图像按 [1-9][1-9][1-9] 的顺序重复......但令我惊讶的是,所有 30 个 listViewItems 中的文本都不同。

在调试时,我发现我的图像对象的 setter 仅针对前 9 个项目被调用。有人可以阐明其他系统组件(系统图像/TextBlock 工作正常)如何获得新的元素值吗?

相关类属性的代码片段:

public sealed partial class CustomImage : UserControl
{

public static readonly DependencyProperty ImageSourceStringProperty = DependencyProperty.Register("ImageSourceString", typeof(string), typeof(CustomImage), new PropertyMetadata(null, new PropertyChangedCallback(ImageSourceStringChanged)));
public string ImageSourceString
{
get { return (string)GetValue(ImageSourceStringProperty); }
set
{
//THIS NEVER GETS HIT FOR ITEMS AFTER 9th ITEM
SetValue(ImageSourceStringProperty, value);
//{More code here}
}
}
}

Xaml Usage
<ListView ItemsSource="{Binding}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<custom:customImage x:Name="Img" ImageSourceString="{Binding ImgPath}"/>
<TextBlock Grid.Column="1" Text="{Binding Name}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

我错过了它应该如何工作吗?如果有什么不清楚的地方,请告诉我,我可以澄清。

最佳答案

依赖属性的gettersetter不能保证运行,我们最好不要在setter中放入任何其他代码.请注意 Custom dependency properties 中的以下警告 :

In all but exceptional circumstances, your wrapper implementations should perform only the GetValue and SetValue operations. Otherwise, you'll get different behavior when your property is set via XAML versus when it is set via code. For efficiency, the XAML parser bypasses wrappers when setting dependency properties; whenever possible, it uses the registry of dependency properties.

因此,我们可以使用 ImageSourceStringChanged 方法对新值进行操作,而不是在属性的 setter 中使用react,如下所示:

private static void ImageSourceStringChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
CustomImage currentImage = obj as CustomImage;
string oldValue = e.OldValue as string;
string newValue = e.NewValue as string;
MainPage.logMsg("ImageSource = " + newValue);
if (oldValue == null || !oldValue.Equals(newValue))
{
string path = newValue;
if (string.IsNullOrEmpty(path))
{
Uri imageFileUri = new Uri("ms-appx:///Assets/Images/failed.png");
currentImage.mainImage.ImageSource = new BitmapImage(imageFileUri);
}
else
{
Uri imageFileUri = null;
try
{
imageFileUri = new Uri(path);
}
catch
{
imageFileUri = new Uri("ms-appx:///Assets/Images/failed.png");
}
if (imageFileUri != null)
{
currentImage.mainImage.ImageSource = new BitmapImage(imageFileUri);
}
}
}
}

另外,因为你的DependencyProperty的类型是string,你不需要比较OldValueNewValue 因为回调只有在值改变时才会被调用。参见 Property changed behavior for structures and enumerations .

If the type of a DependencyProperty is an enumeration or a structure, the may be invoked even if the internal values of the structure or the enumeration value did not change. This is different from a system primitive such as a string where it only is invoked if the value changed.

所以CustomImage的完整代码可能是这样的:

public sealed partial class CustomImage : UserControl
{
public static readonly DependencyProperty ImageSourceStringProperty = DependencyProperty.Register("ImageSourceString", typeof(string), typeof(CustomImage), new PropertyMetadata(null, new PropertyChangedCallback(ImageSourceStringChanged)));

public string ImageSourceString
{
get { return (string)GetValue(ImageSourceStringProperty); }
set
{
SetValue(ImageSourceStringProperty, value);
}
}

private static void ImageSourceStringChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
CustomImage currentImage = obj as CustomImage;
string path = e.NewValue as string;
MainPage.logMsg("ImageSource = " + path);

if (string.IsNullOrEmpty(path))
{
Uri imageFileUri = new Uri("ms-appx:///Assets/Images/failed.png");
currentImage.mainImage.ImageSource = new BitmapImage(imageFileUri);
}
else
{
Uri imageFileUri = null;
try
{
imageFileUri = new Uri(path);
}
catch
{
imageFileUri = new Uri("ms-appx:///Assets/Images/failed.png");
}
if (imageFileUri != null)
{
currentImage.mainImage.ImageSource = new BitmapImage(imageFileUri);
}
}
}

public CustomImage()
{
this.InitializeComponent();
}
}

关于c# - 虚拟化不改变新可见项目的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36088429/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com