首页 > 解决方案 > 如何从超出范围的可观察对象触发方法

问题描述

我有一个改变的 ListView。此 ListView 位于 LinearLayout 内部,如果 ListView 项目包含某种类型的项目,则该图标还显示为复选标记。如果没有任何项目属于该类型,则显示“X”。

在下面的代码中,Console.WriteLine 有效。

在 ListView 适配器上调用 NotifyDataSetChanged 后,如何更新图标(也称为重绘函数)。该函数超出了观察者的范围,不能在 OnChanged 内部调用。

private void Init () {
    view = ((Activity)cx).LayoutInflater.Inflate(Resource.Layout.MyPage, this);

    eventsListAdapter?.Dispose();
    eventsListAdapter = new EventsAdapter(
        context,
        EventListDisplay.DefaultView,
        dateCurrentlyDisplayed);

    var myObserver = new MyDataSetObserver();
    eventsListAdapter.RegisterDataSetObserver(myObserver);
}

private void Redraw () {
    // UPDATE ICON HERE
}

public class MyDataSetObserver : DataSetObserver
{
    public override void OnChanged()
    {
        base.OnChanged();
        Console.WriteLine("Change was observerd");


        OnDataChanged(new DataChangedEventArgs() { DataChanged = 1, TimeChanged = DateTime.Now });

        // This area is hit, but how do I call the Redraw method above? It is out of scope
    }
}

/// 编辑:我尝试过的东西有效!有什么不对劲吗?

private void Init () {
    view = ((Activity)cx).LayoutInflater.Inflate(Resource.Layout.MyPage, this);

    eventsListAdapter?.Dispose();
    eventsListAdapter = new EventsAdapter(
        context,
        EventListDisplay.DefaultView,
        dateCurrentlyDisplayed);

    var myObserver = new MyDataSetObserver();
    eventsListAdapter.RegisterDataSetObserver(myObserver);

    myObserver.DataChanged += OnDataChanged;
}

private void Redraw () {
    // UPDATE ICON HERE
}

private void OnDataChanged(object sender, EventArgs e) {
    Redraw();
}

// Added the last four event handler pieces
public class MyDataSetObserver : DataSetObserver
    {
        public override void OnChanged()
        {
            base.OnChanged();
            g.ToastShort("Change was observerd");
        }

        public event EventHandler DataChanged;

        protected virtual void OnDataChanged(EventArgs e)
        {
            EventHandler handler = DataChanged;
            handler?.Invoke(this, e);
        }

        public delegate void DataChangedEventHandler(object sender, DataChangedEventArgs e);

        public class DataChangedEventArgs : EventArgs
        {
            public int DataChanged { get; set; }
            public DateTime TimeChanged { get; set; }
        }

    }

标签: c#xamarin

解决方案


您可以使用消息中心通知您的活动在被击中Redraw()时调用。OnChanged

MessagingCenter 是一种减少耦合的简单方法,尤其是在视图模型之间。它可用于发送和接收简单消息或在类之间传递参数。类应该取消订阅他们不再希望接收的消息。

在中OnChanged(),每次命中时发送一条消息:

  public override void OnChanged()
        {
            base.OnChanged();
            Console.WriteLine("Change was observerd");

            // This area is hit, but how do I call the Redraw method above? It is out of scope

            MessagingCenter.Send<object>(this, "needRedraw");

        }

在您的Init()中,订阅needRedraw消息并在发送“needRedraw”消息时调用 redraw:

private void Init()
        {
            view = ((Activity)cx).LayoutInflater.Inflate(Resource.Layout.MyPage, this);

            eventsListAdapter?.Dispose();
            eventsListAdapter = new EventsAdapter(
                context,
                EventListDisplay.DefaultView,
                dateCurrentlyDisplayed);

            var myObserver = new MyDataSetObserver();
            eventsListAdapter.RegisterDataSetObserver(myObserver);

            MessagingCenter.Subscribe<object>(this, "needRedraw", (sender) => {
                // do something whenever the "needRedraw" message is sent
                Redraw();
            });
        }

推荐阅读