属性绑定数据绑定思路

/// 方案对比:
/// 表现层监听消息--->数据层改变发消息---->表现层收到消息,表现层改变
/// 表现层监听消息--->数据层改变会自动发消息(少写了发消息的代码),表现层改变
/// 优点:少写了发消息的代码

可以说是另外一种思路,但是也可以其他办法解决,自动发消息这个过程,这里我实现了个

核心代码

复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using UnityEngine;

/// <summary>
/// 属性绑定
/// </summary>
/// <typeparam name="T"></typeparam>
public class BindableProperty<T>
{
    private List<Action> changeList = new List<Action>();
    private T _data;

    public BindableProperty(T data)
    {
        _data = data;
    }

    public T data
    {
        get
        {
            return _data;
        }
        set
        {
            _data = value;
            DispatchAll();
        }
    }

    public void AddListener(Action ac)
    {
        if (!changeList.Contains(ac))
        {
            changeList.Add(ac);
        }
        else
        {
            Debug.LogWarning("重复监听");
        }
    }

    public void RemoveListener(Action ac)
    {
        if (changeList.Contains(ac))
        {
            changeList.Remove(ac);
        }
        else
        {
            Debug.LogWarning("移除的消息不存在");
        }
    }

    public void ClearListener()
    {
        changeList.Clear();
        Debug.Log("清理成功");
    }

    private void DispatchAll()
    {
        foreach (var item in changeList)
        {
            item();
        }
    }
}

/// <summary>
/// List
/// 使用了ReadOnlyCollection作为保护,使用IReadOnlyList也是可以
/// 通过Add Remove  Update  Clear 对数据进行操作
/// </summary>
/// <typeparam name="T"></typeparam>
public class BindableList<T>
{
    private List<Action> changeList = new List<Action>();
    private List<T> _data;

    public BindableList()
    {
        _data = new List<T>();
    }

    public ReadOnlyCollection<T> data
    {
        get {
            return _data.AsReadOnly();
        }
        private set {
            
        }
    }

    public void Add(T t)
    {
        _data.Add(t);
        DispatchAll();
    }

    public void Remove(T t)
    {
        if (_data.Contains(t))
        {
            _data.Remove(t);
            DispatchAll();
        }
    }

    public void Clear()
    {
        _data.Clear();
        DispatchAll();
    }

    public void Update(List<T> _list)
    {
        _data = _list;
        DispatchAll();
    }

    public void AddListener(Action ac)
    {
        if (!changeList.Contains(ac))
        {
            changeList.Add(ac);
        }
        else
        {
            Debug.LogWarning("重复监听");
        }
    }

    public void RemoveListener(Action ac)
    {
        if (changeList.Contains(ac))
        {
            changeList.Remove(ac);
        }
        else
        {
            Debug.LogWarning("移除的消息不存在");
        }
    }

    public void ClearListener()
    {
        changeList.Clear();
        Debug.Log("清理成功");
    }

    private void DispatchAll()
    {
        foreach (var item in changeList)
        {
            item();
        }
    }
}

/// <summary>
/// Dic
/// 使用IReadOnlyDictionary作为保护
/// 通过Add RemoveByKey  Update  Clear 对数据进行操作
/// </summary>
/// <typeparam name="T"></typeparam>
public class BindableDic<T,V>
{
    private List<Action> changeList = new List<Action>();
    private Dictionary<T, V> _data;
    public IReadOnlyDictionary<T, V> data
    { get { return _data; } }

    public BindableDic()
    {
        _data = new Dictionary<T, V>();
    }

    public void Add(T t, V v)
    {
        _data.Add(t,v);
        DispatchAll();
    }

    public void RemoveByKey(T _key)
    {
        if (_data.ContainsKey(_key))
        {
            _data.Remove(_key);
            DispatchAll();
        }
    }

    public void Clear()
    {
        _data.Clear();
        DispatchAll();
    }

    public void Update(Dictionary<T,V> _dic)
    {
        _data = _dic;
        DispatchAll();
    }

    public void AddListener(Action ac)
    {
        if (!changeList.Contains(ac))
        {
            changeList.Add(ac);
        }
        else
        {
            Debug.LogWarning("重复监听");
        }
    }

    public void RemoveListener(Action ac)
    {
        if (changeList.Contains(ac))
        {
            changeList.Remove(ac);
        }
        else
        {
            Debug.LogWarning("移除的消息不存在");
        }
    }

    public void ClearListener()
    {
        changeList.Clear();
        Debug.Log("清理成功");
    }

    private void DispatchAll()
    {
        foreach (var item in changeList)
        {
            item();
        }
    }
}
复制代码

 

调用,在unity实现

复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 数据自动变化
/// 
/// 方案对比:
/// 表现层监听消息--->数据层改变发消息---->表现层收到消息,表现层改变
/// 表现层监听消息--->数据层改变会自动发消息(少写了发消息的代码),表现层改变
/// 优点:少写了发消息的代码
/// </summary>
public class TestBind : MonoBehaviour
{
    BindableProperty<int> hpData = new BindableProperty<int>(100);
    BindableList<int> friendList = new BindableList<int>();
    BindableDic<int, string> myDic = new BindableDic<int, string>();

    // Start is called before the first frame update
    void Start()
    {
        hpData.AddListener(delegate() {
            print("hh" + hpData.data);
        });

        friendList.AddListener(delegate () {
            print("ff" + friendList.data.Count);
        });

        myDic.AddListener(delegate ()
        {
            print("dd" + myDic.data.Count);
        });
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Q))
        {
            hpData.data = 99;
        }

        if (Input.GetKeyDown(KeyCode.W))
        {
            friendList.Add(658);
            friendList.Add(638);
        }

        if (Input.GetKeyDown(KeyCode.E))
        {
            print(friendList.data.Count);
        }

        if (Input.GetKeyDown(KeyCode.R))
        {
            myDic.Add(1,"sas");
            myDic.Add(2, "sas2212");
            print(myDic.data.Count);
        }
    }
}
复制代码

 

posted @   三页菌  阅读(321)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示