虚拟化不会更改新可见项的属性

我目前在listView中使用自定义Image对象( 对象周围的包装器)。 当新的列表视图项可见(已实现)时,我的自定义Image对象的属性不会更改。

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

在调试时,我发现只为前9个项目调用了我的图像对象的setter。 有人能否了解其他系统组件(System Image / 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               

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

不保证依赖属性的gettersetter可以运行,我们最好不要在setter放置任何其他代码。 请注意以下自定义依赖项属性中的 注意事项

除了特殊情况外,您的包装器实现应该只执行GetValue和SetValue操作。 否则,当您通过XAML设置属性时,通过代码设置属性时,您将获得不同的行为。 为了提高效率,XAML解析器在设置依赖项属性时会绕过包装器; 只要可能,它使用依赖项属性的注册表。

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

 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因为只有在值更改时才会调用回调。 请参阅结构和枚举的属性更改行为 。

如果DependencyProperty的类型是枚举或结构,即使结构的内部值或枚举值没有改变,也可以调用它。 这与系统原语(如字符串)不同,只有在值更改时才会调用它。

所以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(); } }