>  기사  >  백엔드 개발  >  WPF 데이터 바인딩의 핵심 기술

WPF 데이터 바인딩의 핵심 기술

零下一度
零下一度원래의
2017-06-23 16:04:092188검색

WPF의 핵심 기술 장점 중 하나는 데이터 바인딩입니다. 데이터 바인딩은 데이터에 대한 작업을 통해 인터페이스를 업데이트할 수 있습니다.

데이터 바인딩에 가장 일반적으로 사용되는 클래스는 ObservableCollection8742468051c85b06f0a0af9e3e506b5c 및 Dictionary6e081e925c6a2fa99508161fe1ff33ed입니다.

ObservableCollection은 동적 데이터 컬렉션을 나타냅니다. 이 컬렉션은 항목이 추가되거나 항목이 제거되거나 전체 목록이 새로 고쳐질 때 알림을 제공합니다. 컬렉션 데이터를 업데이트하여 인터페이스 표시를 업데이트할 수 있습니다.

Dictionary 사전 클래스는 검색 및 데이터 연산 성능이 매우 낮기 때문에 일부 구성 항목 모음을 이를 사용하여 저장합니다.

그래서 다들 ObservableCollection과 Dictionary를 결합한 클래스가 있을까 고민하다가 ObservableDictionary 클래스가 탄생하게 되었습니다.

내가 아는 한 ObservableDictionary 클래스의 버전은 Dr.WPF의 사전에 대한 ItemsControl입니다. 대부분의 다른 버전은 이를 참조하여 수정됩니다. , 나는 무지하다) ).

오늘 제가 제공하는 버전은 인터넷에 있는 다른 버전과 Dr.WPF에 있는 버전도 참조합니다.

Dr.WPF의 정의는 다음과 같습니다.

public class ObservableDictionary <TKey, TValue> :
        IDictionary<TKey, TValue>,
        ICollection<KeyValuePair<TKey, TValue>>,
        IEnumerable<KeyValuePair<TKey, TValue>>,
        IDictionary,
        ICollection,
        IEnumerable,
        ISerializable,
        IDeserializationCallback,
        INotifyCollectionChanged,
        INotifyPropertyChanged

자세히 살펴보면 여기에 상속된 인터페이스는 다음을 추가한 것을 제외하면 Dictionaryb6842da76bed01162354d37c4f2d3464에서 상속한 인터페이스와 거의 동일하다는 것을 알 수 있습니다. INotifyCollectionChanged, INotifyPropertyChanged

따라서 제가 오늘 제공하는 버전은 Dictionaryb6842da76bed01162354d37c4f2d3464 및 INotifyCollectionChanged, INotifyPropertyChanged를 직접 상속합니다.

테스트해본 결과 버그도 없고 성능도 뛰어납니다. 코드는 아래와 같습니다.

    public class ObservableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, INotifyCollectionChanged, INotifyPropertyChanged
    {
        public ObservableDictionary()
            : base()
        { }

        private int _index;
        public event NotifyCollectionChangedEventHandler CollectionChanged;
        public event PropertyChangedEventHandler PropertyChanged;

        public new KeyCollection Keys
        {
            get { return base.Keys; }
        }

        public new ValueCollection Values
        {
            get { return base.Values; }
        }

        public new int Count 
        {
            get { return base.Count; }
        }

        public new TValue this[TKey key]
        {
            get { return this.GetValue(key); }
            set { this.SetValue(key, value); }
        }

        public TValue this[int index]
        {
            get { return this.GetIndexValue(index); }
            set { this.SetIndexValue(index, value); }
        }

        public new void Add(TKey key, TValue value)
        {
            base.Add(key, value);
            this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, this.FindPair(key), _index));
            OnPropertyChanged("Keys");
            OnPropertyChanged("Values");
            OnPropertyChanged("Count");
        }

        public new void Clear()
        {
            base.Clear();
            this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
            OnPropertyChanged("Keys");
            OnPropertyChanged("Values");
            OnPropertyChanged("Count");
        }

        public new bool Remove(TKey key)
        {
            var pair = this.FindPair(key);
            if (base.Remove(key))
            {
                this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, pair, _index));
                OnPropertyChanged("Keys");
                OnPropertyChanged("Values");
                OnPropertyChanged("Count");
                return true;
            }
            return false;
        }

        protected void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            if (this.CollectionChanged != null)
            {
                this.CollectionChanged(this, e);
            }
        }

        protected void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #region private方法
        private TValue GetIndexValue(int index)
        {
            for (int i = 0; i < this.Count; i++)
            {
                if (i == index)
                {
                    var pair = this.ElementAt(i);
                    return pair.Value;
                }
            }

            return default(TValue);
        }

        private void SetIndexValue(int index, TValue value)
        {
            try
            {
                var pair = this.ElementAtOrDefault(index);
                SetValue(pair.Key, value);                
            }
            catch (Exception)
            {
                
            }
        }

        private TValue GetValue(TKey key)
        {
            if (base.ContainsKey(key))
            {
                return base[key];
            }
            else
            {
                return default(TValue);
            }
        }

        private void SetValue(TKey key, TValue value)
        {
            if (base.ContainsKey(key))
            {
                var pair = this.FindPair(key);
                int index = _index;
                base[key] = value;
                var newpair = this.FindPair(key);
                this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newpair, pair, index));
                OnPropertyChanged("Values");
                OnPropertyChanged("Item[]");
            }
            else
            {
                this.Add(key, value);
            }
        }

        private KeyValuePair<TKey, TValue> FindPair(TKey key)
        {
            _index = 0;
            foreach (var item in this)
            {
                if (item.Key.Equals(key))
                {
                    return item;
                }
                _index++;
            }
            return default(KeyValuePair<TKey, TValue>);
        }

        private int IndexOf(TKey key)
        {
            int index = 0;
            foreach (var item in this)
            {
                if (item.Key.Equals(key))
                {
                    return index;
                }
                index++;

            }
            return -1;
        }

        #endregion

    }

확장 측면에서는 더 기술적이고 확장성이 뛰어난 Dr.WPF 버전으로 수정할 수 있습니다. !

위 내용은 WPF 데이터 바인딩의 핵심 기술의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.