listview - Xamarin 找到将我的对象作为数据上下文的视图单元
问题描述
我有一个通过 dataBinding 填充的 ListView,它的 viewCells 通过 DataTemplateSelector 进行模板化。
我的 ListView 看起来像这样:
<ListView x:Name="PuzzlesContainer"
ItemsSource="{x:Static gameBrain:GameItems.Puzzles}"
RowHeight="167"
ItemTemplate="{StaticResource PuzzleDataTemplateSelector}"/>
然后在某个时候,我将在一个拼图中进行修改,该拼图需要用在其 viewCell 上的画布中绘制的线条来表示(来自 DataTemplate)
如何访问将我的拼图作为 DataContext 的 ViewCell 以便能够手动更新 Canvas ?
解决方案
在列表中创建一个从 ViewCell 派生的自定义控件。在 xaml 中您将拥有一个模板,在代码隐藏中您将设置值而不将 xaml 绑定到数据。它会更新得更快。从理论上讲,您不需要模板选择器,因为在代码隐藏中您现在可以用您的单元格做所有事情。你的细胞等级:
private INotifyPropertyChanged _oldBindingContext;
//this normally fires when you set your list ItemsSource
protected override void OnBindingContextChanged()
{
if (_oldBindingContext != null)
{
_oldBindingContext.PropertyChanged -= OnBindingContextPropertyChanged;
}
if (BindingContext != null)
{
INotifyPropertyChanged ctx = null;
try
{
ctx = (INotifyPropertyChanged)BindingContext;
}
catch
{
base.OnBindingContextChanged();
return;
}
ctx.PropertyChanged += OnBindingContextPropertyChanged;
}
_oldBindingContext = (INotifyPropertyChanged)BindingContext;
OnCellBindingContextChanged();
base.OnBindingContextChanged();
}
public virtual void OnCellBindingContextChanged()
{
if (BindingContext == null) return;
//update your xaml here.
var model = (MyItemCLass)BindingContext;
MyXamlTextBox.Text = model.Title;
}
//you are left with the challenge to call dispose manually when your page destroys.
//im calling this from my custom list for every cell when page pops up
public void Dispose()
{
if (BindingContext != null)
{
INotifyPropertyChanged ctx = null;
try
{
ctx = (INotifyPropertyChanged)BindingContext;
ctx.PropertyChanged -= OnBindingContextPropertyChanged;
}
catch
{
}
}
}
//and this is what your question is about:
//when a single property of your model changes we land here to react
private void OnBindingContextPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e== null || BindingContext==null) return;
var = PropertyName = e?.PropertyName;
//todo more checks
var propertyInfo = BindingContext.GetType().GetProperty(propertyName);
if (propertyInfo == null) return;
if (propertyName == "IsFavorite")
{
UpdateFav((MySupaItem)BindingContext);
}
}
推荐阅读
- javascript - 带按钮的 Toggle() 方法
- laravel - Laravel:具有 Servcie 容器的实例上的不同实现
- r - 在 R stringr 中第 n 次出现后匹配
- algorithm - 我们能解决这种 DP 中的 0-1 Multiple Knapsack 问题吗?
- angular - ngx-datatable 水平滚动在移动设备上不起作用
- java - 如何将 SpringBoot JMX bean 与 Jolokia 连接?
- ember.js - Ember 构建问题:“不能同时使用 decorators 和 decorators-legacy 插件”
- python - 我的类构造函数的“接口”应该是我的类的一部分吗?(如何?)
- c - 在 C 中,为什么有时我只需要 getchar() 来删除字符?
- r - 使用 R Keras 包时,如何获取在 R 中每次调整运行中使用的标志值?