背景:基本上,我正在使用自定义Android渲染器在Xamarin.Forms中创建一个Grid系统,因为内置的Grid实现对于我们想要做的事情来说太慢了(它可以'我们需要同时滚动100,000个单元格。我已经成功地做了这个过度耦合,现在我正在重构我的主管问的方式,我遇到了一个问题。
方案:
//In Xamarin.Forms project
class GridItems : BindableObject {
//Handles/contains all logic to how this grid will be laid out and its children
}
//In Xamarin.Forms project
class Grid : View {
GridItems Source { get; set; }
}
//In Xamarin.Android project
class GridRenderer {
OnElementPropertyChanged() {
//Here I can check what properties inside Grid changed
}
}
这显然是非常简化的,但是这样设置的原因是你可以简单地继承GridItems来修改网格所接受的项目类型,单元格/列的字符串值应该是什么,等等。并重用Grid和GridRenderer类。
问题:
当GridItems在其自身内被修改时,我需要通知Grid.GridItems。 GridItems可以引发它的属性更改事件,但是只会触发本地属性。我基本上需要GridItems才能告诉Grid"我已经改变了,提升你的GridItems属性改变了事件",这样GridRenderer可以看到GridItems已经改变(自Grid改变)和Invalidate本身,重绘在屏幕。
有没有一种方法可以通知包含对象属性已从属性本身更改?或者我是否接近这个问题呢?
答案 0 :(得分:1)
所以我设法找到了一种方法来做到这一点,但它可能对大多数未来的人不起作用,因为它非常适合我的场景。
基本上,Grid和GridItem都共享一个ViewModel(页面ViewModel)。这意味着当GridItems的绑定被修改时,ViewModel可以通过绑定简单地通知Grid,所以它更像是ViewModel负责。
我在Grid中创建了一个名为“Invalidate”的可绑定布尔值。每当ViewModel修改GridItems的子绑定时,它都会通过将其设置为true来修改Invalidate绑定。
现在在自定义渲染器上,无论何时为Grid触发ElementPropertyChange,它都会检查Invalidate是否已触发& Invalidate现在设置为true。在这种情况下,它只是在元素中将Invalidate重置为false,然后在其自身上调用Invalidate(强制Draw事件在可能的情况下重新启动并重新加载屏幕)。