Xamarin查找将我的对象作为数据上下文的视单元

时间:2018-10-10 15:01:45

标签: listview xamarin

我有一个通过dataBinding填充的ListView,它的viewCells通过DataTemplateSelector进行了模板化。

我的ListView看起来像这样:

<ListView x:Name="PuzzlesContainer"
          ItemsSource="{x:Static gameBrain:GameItems.Puzzles}"
          RowHeight="167"
          ItemTemplate="{StaticResource PuzzleDataTemplateSelector}"/>

然后在某个时候,我将在一个Puzzle中进行修改,需要用在viewCell上的画布中绘制的线条来表示(来自DataTemplate)

我该如何访问困扰我的ViewCell作为DataContext,以便能够手动更新Canvas?

1 个答案:

答案 0 :(得分:0)

在列表内创建一个从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);
                }

    }