SimpleWindow
载入中...
搜索中...
未找到
Binding.h
1#pragma once
2
3#include "INotifyObjectDead.h"
4#include "INotifyPropertyChanged.h"
5#include "IValueConverter.h"
6
7namespace sw
8{
12 enum class BindingMode {
16 OneTime,
17
21 OneWay,
22
26 OneWayToSource,
27
31 TwoWay,
32 };
33
38 {
39 public:
43 virtual ~BindingBase() = default;
44
45 public:
50 virtual bool UpdateTarget() = 0;
51
56 virtual bool UpdateSource() = 0;
57
61 virtual FieldId GetTargetPropertyId() const = 0;
62
66 virtual FieldId GetSourcePropertyId() const = 0;
67 };
68
72 class Binding final : public BindingBase
73 {
74 private:
78 BindingMode _mode;
79
83 DynamicObject *_targetObject;
84
88 DynamicObject *_sourceObject;
89
93 FieldId _targetPropertyId;
94
98 FieldId _sourcePropertyId;
99
103 void *_converter;
104
108 void (*_converterDeleter)(void *);
109
113 Func<Binding *, bool> _updateTargetFunc;
114
118 Func<Binding *, bool> _updateSourceFunc;
119
120 private:
124 Binding() = default;
125
126 Binding(const Binding &) = delete; // 删除拷贝构造函数
127 Binding(Binding &&) = delete; // 删除移动构造函数
128 Binding &operator=(const Binding &) = delete; // 删除拷贝赋值运算符
129 Binding &operator=(Binding &&) = delete; // 删除移动赋值运算符
130
131 public:
135 virtual ~Binding()
136 {
137 UnregisterNotifications();
138
139 if (_converterDeleter && _converter) {
140 _converterDeleter(_converter);
141 }
142 }
143
148 virtual bool UpdateTarget() override
149 {
150 bool result = false;
151
152 if (_updateTargetFunc) {
153 result = _updateTargetFunc(this);
154 }
155 return result;
156 }
157
162 virtual bool UpdateSource() override
163 {
164 bool result = false;
165
166 if (_updateSourceFunc) {
167 result = _updateSourceFunc(this);
168 }
169 return result;
170 }
171
175 virtual FieldId GetTargetPropertyId() const override
176 {
177 return _targetPropertyId;
178 }
179
183 virtual FieldId GetSourcePropertyId() const override
184 {
185 return _sourcePropertyId;
186 }
187
191 BindingMode GetBindingMode() const
192 {
193 return _mode;
194 }
195
200 {
201 return _targetObject;
202 }
203
208 {
209 return _sourceObject;
210 }
211
215 void SetBindingMode(BindingMode mode)
216 {
217 if (_mode != mode) {
218 _mode = mode;
219 OnBindingChanged();
220 }
221 }
222
227 {
228 if (_targetObject != target) {
229 UnregisterNotifications();
230 _targetObject = target;
231 RegisterNotifications();
232 OnBindingChanged();
233 }
234 }
235
240 {
241 if (_sourceObject != source) {
242 UnregisterNotifications();
243 _sourceObject = source;
244 RegisterNotifications();
245 OnBindingChanged();
246 }
247 }
248
253 {
254 if (_targetObject != target ||
255 _sourceObject != source) //
256 {
257 UnregisterNotifications();
258 _targetObject = target;
259 _sourceObject = source;
260 RegisterNotifications();
261 OnBindingChanged();
262 }
263 }
264
265 private:
269 void RegisterNotifications()
270 {
271 INotifyPropertyChanged *targetNotifObj = nullptr;
272 INotifyPropertyChanged *sourceNotifObj = nullptr;
273
274 if (_targetObject != nullptr && _targetObject->IsType(&targetNotifObj)) {
275 targetNotifObj->PropertyChanged +=
276 PropertyChangedEventHandler(*this, &Binding::OnTargetPropertyChanged);
277 }
278 if (_sourceObject != nullptr && _sourceObject->IsType(&sourceNotifObj)) {
279 sourceNotifObj->PropertyChanged +=
280 PropertyChangedEventHandler(*this, &Binding::OnSourcePropertyChanged);
281 }
282
283 INotifyObjectDead *targetNotifObjDead = nullptr;
284 INotifyObjectDead *sourceNotifObjDead = nullptr;
285
286 if (_targetObject != nullptr && _targetObject->IsType(&targetNotifObjDead)) {
287 targetNotifObjDead->ObjectDead +=
288 ObjectDeadEventHandler(*this, &Binding::OnTargetObjectDead);
289 }
290 if (_sourceObject != nullptr && _sourceObject->IsType(&sourceNotifObjDead)) {
291 sourceNotifObjDead->ObjectDead +=
292 ObjectDeadEventHandler(*this, &Binding::OnSourceObjectDead);
293 }
294 }
295
299 void UnregisterNotifications()
300 {
301 INotifyPropertyChanged *targetNotifObj = nullptr;
302 INotifyPropertyChanged *sourceNotifObj = nullptr;
303
304 if (_targetObject != nullptr && _targetObject->IsType(&targetNotifObj)) {
305 targetNotifObj->PropertyChanged -=
306 PropertyChangedEventHandler(*this, &Binding::OnTargetPropertyChanged);
307 }
308 if (_sourceObject != nullptr && _sourceObject->IsType(&sourceNotifObj)) {
309 sourceNotifObj->PropertyChanged -=
310 PropertyChangedEventHandler(*this, &Binding::OnSourcePropertyChanged);
311 }
312
313 INotifyObjectDead *targetNotifObjDead = nullptr;
314 INotifyObjectDead *sourceNotifObjDead = nullptr;
315
316 if (_targetObject != nullptr && _targetObject->IsType(&targetNotifObjDead)) {
317 targetNotifObjDead->ObjectDead -=
318 ObjectDeadEventHandler(*this, &Binding::OnTargetObjectDead);
319 }
320 if (_sourceObject != nullptr && _sourceObject->IsType(&sourceNotifObjDead)) {
321 sourceNotifObjDead->ObjectDead -=
322 ObjectDeadEventHandler(*this, &Binding::OnSourceObjectDead);
323 }
324 }
325
329 void OnTargetPropertyChanged(INotifyPropertyChanged &sender, FieldId propertyId)
330 {
331 if (propertyId != _targetPropertyId) {
332 return;
333 }
334
335 if (_mode == BindingMode::TwoWay ||
336 _mode == BindingMode::OneWayToSource) {
337 UpdateSource();
338 }
339 }
340
344 void OnSourcePropertyChanged(INotifyPropertyChanged &sender, FieldId propertyId)
345 {
346 if (propertyId != _sourcePropertyId) {
347 return;
348 }
349
350 if (_mode == BindingMode::TwoWay ||
351 _mode == BindingMode::OneWay) {
352 UpdateTarget();
353 }
354 }
355
359 void OnTargetObjectDead(INotifyObjectDead &sender)
360 {
361 SetTargetObject(nullptr);
362 }
363
367 void OnSourceObjectDead(INotifyObjectDead &sender)
368 {
369 SetSourceObject(nullptr);
370 }
371
375 void OnBindingChanged()
376 {
377 switch (_mode) {
378 case BindingMode::OneTime:
379 case BindingMode::OneWay:
380 case BindingMode::TwoWay: {
381 UpdateTarget();
382 break;
383 }
384 case BindingMode::OneWayToSource: {
385 UpdateSource();
386 break;
387 }
388 }
389 }
390
401 template <typename TTargetValue, typename TSourceValue>
402 static Binding *Create(DynamicObject *target, FieldId targetPropertyId,
403 DynamicObject *source, FieldId sourcePropertyId,
404 BindingMode mode, IValueConverter<TSourceValue, TTargetValue> *converter)
405 {
406 auto binding = new Binding;
407
408 binding->_targetObject = target;
409 binding->_sourceObject = source;
410 binding->_targetPropertyId = targetPropertyId;
411 binding->_sourcePropertyId = sourcePropertyId;
412
413 binding->_mode = mode;
414 binding->_converter = converter;
415
416 binding->_converterDeleter = [](void *ptr) {
417 delete reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(ptr);
418 };
419 return binding;
420 }
421
422 public:
434 template <
435 typename TTargetObject,
436 typename TTargetProperty,
437 typename TSourceObject,
438 typename TSourceProperty>
441 BindingMode mode,
443 -> typename std::enable_if<
446 std::is_base_of<DynamicObject, TTargetObject>::value &&
447 std::is_base_of<DynamicObject, TSourceObject>::value &&
448 std::is_same<typename TTargetProperty::TValue, typename TSourceProperty::TValue>::value,
449 Binding *>::type
450 {
451 using TTargetValue = typename TTargetProperty::TValue;
452 using TSourceValue = typename TSourceProperty::TValue;
453
454 auto binding = Create(
457
458 // update target action
461 {
463 reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(binding->_converter);
464
465 if (targetSetter == nullptr ||
466 sourceGetter == nullptr ||
467 binding->_targetObject == nullptr ||
468 binding->_sourceObject == nullptr) {
469 return false;
470 }
471
472 if (converter) {
474 *binding->_targetObject,
475 converter->Convert(sourceGetter(*binding->_sourceObject)));
476 } else {
478 *binding->_targetObject,
479 sourceGetter(*binding->_sourceObject));
480 }
481 return true;
482 };
483
484 // update source action
487 {
489 reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(binding->_converter);
490
491 if (targetGetter == nullptr ||
492 sourceSetter == nullptr ||
493 binding->_targetObject == nullptr ||
494 binding->_sourceObject == nullptr) {
495 return false;
496 }
497
498 if (converter) {
500 *binding->_sourceObject,
501 converter->ConvertBack(targetGetter(*binding->_targetObject)));
502 } else {
504 *binding->_sourceObject,
505 targetGetter(*binding->_targetObject));
506 }
507 return true;
508 };
509
510 binding->RegisterNotifications();
511 binding->OnBindingChanged();
512 return binding;
513 }
514
525 template <
526 typename TTargetObject,
527 typename TTargetProperty,
528 typename TSourceObject,
529 typename TSourceProperty>
531 DynamicObject *source,
533 BindingMode mode,
535 -> typename std::enable_if<
538 std::is_base_of<DynamicObject, TTargetObject>::value &&
539 std::is_base_of<DynamicObject, TSourceObject>::value &&
540 std::is_same<typename TTargetProperty::TValue, typename TSourceProperty::TValue>::value,
541 Binding *>::type
542 {
543 return Create(nullptr, targetProperty, source, sourceProperty, mode, converter);
544 }
545
555 template <
556 typename TTargetObject,
557 typename TTargetProperty,
558 typename TSourceObject,
559 typename TSourceProperty>
562 BindingMode mode,
564 -> typename std::enable_if<
567 std::is_base_of<DynamicObject, TTargetObject>::value &&
568 std::is_base_of<DynamicObject, TSourceObject>::value &&
569 std::is_same<typename TTargetProperty::TValue, typename TSourceProperty::TValue>::value,
570 Binding *>::type
571 {
572 return Create(nullptr, targetProperty, nullptr, sourceProperty, mode, converter);
573 }
574
586 template <
587 typename TTargetObject,
588 typename TTargetProperty,
589 typename TSourceObject,
590 typename TSourceProperty>
593 BindingMode mode,
595 -> typename std::enable_if<
598 std::is_base_of<DynamicObject, TTargetObject>::value &&
599 std::is_base_of<DynamicObject, TSourceObject>::value &&
600 !std::is_same<typename TTargetProperty::TValue, typename TSourceProperty::TValue>::value,
601 Binding *>::type
602 {
603 using TTargetValue = typename TTargetProperty::TValue;
604 using TSourceValue = typename TSourceProperty::TValue;
605
606 auto binding = Create(
609
610 // update target action
613 {
615 reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(binding->_converter);
616
617 if (targetSetter == nullptr ||
618 sourceGetter == nullptr ||
619 converter == nullptr ||
620 binding->_targetObject == nullptr ||
621 binding->_sourceObject == nullptr) {
622 return false;
623 }
624
626 *binding->_targetObject,
627 converter->Convert(sourceGetter(*binding->_sourceObject)));
628 return true;
629 };
630
631 // update source action
634 {
636 reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(binding->_converter);
637
638 if (targetGetter == nullptr ||
639 sourceSetter == nullptr ||
640 converter == nullptr ||
641 binding->_targetObject == nullptr ||
642 binding->_sourceObject == nullptr) {
643 return false;
644 }
645
647 *binding->_sourceObject,
648 converter->ConvertBack(targetGetter(*binding->_targetObject)));
649 return true;
650 };
651
652 binding->RegisterNotifications();
653 binding->OnBindingChanged();
654 return binding;
655 }
656
667 template <
668 typename TTargetObject,
669 typename TTargetProperty,
670 typename TSourceObject,
671 typename TSourceProperty>
673 DynamicObject *source,
675 BindingMode mode,
677 -> typename std::enable_if<
680 std::is_base_of<DynamicObject, TTargetObject>::value &&
681 std::is_base_of<DynamicObject, TSourceObject>::value &&
682 !std::is_same<typename TTargetProperty::TValue, typename TSourceProperty::TValue>::value,
683 Binding *>::type
684 {
685 return Create(nullptr, targetProperty, source, sourceProperty, mode, converter);
686 }
687
697 template <
698 typename TTargetObject,
699 typename TTargetProperty,
700 typename TSourceObject,
701 typename TSourceProperty>
704 BindingMode mode,
706 -> typename std::enable_if<
709 std::is_base_of<DynamicObject, TTargetObject>::value &&
710 std::is_base_of<DynamicObject, TSourceObject>::value &&
711 !std::is_same<typename TTargetProperty::TValue, typename TSourceProperty::TValue>::value,
712 Binding *>::type
713 {
714 return Create(nullptr, targetProperty, nullptr, sourceProperty, mode, converter);
715 }
716 };
717}
数据绑定基类
Definition Binding.h:38
virtual FieldId GetTargetPropertyId() const =0
获取目标属性ID
virtual ~BindingBase()=default
默认析构函数
virtual bool UpdateSource()=0
更新源属性的值
virtual FieldId GetSourcePropertyId() const =0
获取源属性ID
virtual bool UpdateTarget()=0
更新目标属性的值
数据绑定类
Definition Binding.h:73
void SetBindingObjects(DynamicObject *target, DynamicObject *source)
修改目标对象和源对象
Definition Binding.h:252
void SetBindingMode(BindingMode mode)
修改绑定模式
Definition Binding.h:215
static auto Create(DynamicObject *target, TTargetProperty TTargetObject::*targetProperty, DynamicObject *source, TSourceProperty TSourceObject::*sourceProperty, BindingMode mode, IValueConverter< typename TSourceProperty::TValue, typename TTargetProperty::TValue > *converter=nullptr) -> typename std::enable_if< _IsProperty< TTargetProperty >::value &&_IsProperty< TSourceProperty >::value &&std::is_base_of< DynamicObject, TTargetObject >::value &&std::is_base_of< DynamicObject, TSourceObject >::value &&std::is_same< typename TTargetProperty::TValue, typename TSourceProperty::TValue >::value, Binding * >::type
创建绑定对象
Definition Binding.h:439
BindingMode GetBindingMode() const
获取绑定模式
Definition Binding.h:191
DynamicObject * GetTargetObject() const
获取目标对象
Definition Binding.h:199
virtual bool UpdateSource() override
更新源属性的值
Definition Binding.h:162
virtual FieldId GetTargetPropertyId() const override
获取目标属性ID
Definition Binding.h:175
virtual bool UpdateTarget() override
更新目标属性的值
Definition Binding.h:148
DynamicObject * GetSourceObject() const
获取源对象
Definition Binding.h:207
virtual ~Binding()
析构函数
Definition Binding.h:135
static auto Create(TTargetProperty TTargetObject::*targetProperty, TSourceProperty TSourceObject::*sourceProperty, BindingMode mode, IValueConverter< typename TSourceProperty::TValue, typename TTargetProperty::TValue > *converter) -> typename std::enable_if< _IsProperty< TTargetProperty >::value &&_IsProperty< TSourceProperty >::value &&std::is_base_of< DynamicObject, TTargetObject >::value &&std::is_base_of< DynamicObject, TSourceObject >::value &&!std::is_same< typename TTargetProperty::TValue, typename TSourceProperty::TValue >::value, Binding * >::type
创建延迟绑定对象
Definition Binding.h:702
static auto Create(DynamicObject *target, TTargetProperty TTargetObject::*targetProperty, DynamicObject *source, TSourceProperty TSourceObject::*sourceProperty, BindingMode mode, IValueConverter< typename TSourceProperty::TValue, typename TTargetProperty::TValue > *converter) -> typename std::enable_if< _IsProperty< TTargetProperty >::value &&_IsProperty< TSourceProperty >::value &&std::is_base_of< DynamicObject, TTargetObject >::value &&std::is_base_of< DynamicObject, TSourceObject >::value &&!std::is_same< typename TTargetProperty::TValue, typename TSourceProperty::TValue >::value, Binding * >::type
创建绑定对象
Definition Binding.h:591
virtual FieldId GetSourcePropertyId() const override
获取源属性ID
Definition Binding.h:183
static auto Create(TTargetProperty TTargetObject::*targetProperty, DynamicObject *source, TSourceProperty TSourceObject::*sourceProperty, BindingMode mode, IValueConverter< typename TSourceProperty::TValue, typename TTargetProperty::TValue > *converter=nullptr) -> typename std::enable_if< _IsProperty< TTargetProperty >::value &&_IsProperty< TSourceProperty >::value &&std::is_base_of< DynamicObject, TTargetObject >::value &&std::is_base_of< DynamicObject, TSourceObject >::value &&std::is_same< typename TTargetProperty::TValue, typename TSourceProperty::TValue >::value, Binding * >::type
创建延迟绑定对象
Definition Binding.h:530
void SetTargetObject(DynamicObject *target)
修改目标对象
Definition Binding.h:226
void SetSourceObject(DynamicObject *source)
修改源对象
Definition Binding.h:239
static auto Create(TTargetProperty TTargetObject::*targetProperty, TSourceProperty TSourceObject::*sourceProperty, BindingMode mode, IValueConverter< typename TSourceProperty::TValue, typename TTargetProperty::TValue > *converter=nullptr) -> typename std::enable_if< _IsProperty< TTargetProperty >::value &&_IsProperty< TSourceProperty >::value &&std::is_base_of< DynamicObject, TTargetObject >::value &&std::is_base_of< DynamicObject, TSourceObject >::value &&std::is_same< typename TTargetProperty::TValue, typename TSourceProperty::TValue >::value, Binding * >::type
创建延迟绑定对象
Definition Binding.h:560
static auto Create(TTargetProperty TTargetObject::*targetProperty, DynamicObject *source, TSourceProperty TSourceObject::*sourceProperty, BindingMode mode, IValueConverter< typename TSourceProperty::TValue, typename TTargetProperty::TValue > *converter) -> typename std::enable_if< _IsProperty< TTargetProperty >::value &&_IsProperty< TSourceProperty >::value &&std::is_base_of< DynamicObject, TTargetObject >::value &&std::is_base_of< DynamicObject, TSourceObject >::value &&!std::is_same< typename TTargetProperty::TValue, typename TSourceProperty::TValue >::value, Binding * >::type
创建延迟绑定对象
Definition Binding.h:672
Definition Delegate.h:21
动态对象基类
Definition Reflection.h:27
auto IsType(T **pout=nullptr) -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value, bool >::type
判断对象是否为指定类型
Definition Reflection.h:85
属性变更通知接口
Definition INotifyPropertyChanged.h:18
PropertyChangedEventHandler PropertyChanged
当属性值更改时触发的事件
Definition INotifyPropertyChanged.h:23
值转换器接口
Definition IValueConverter.h:14
virtual TTarget Convert(TSourceParam source)=0
将源类型转换为目标类型
virtual TSource ConvertBack(TTargetParam target)=0
将目标类型转换为源类型
static auto GetPropertySetter(TProperty T::*prop) -> typename std::enable_if< _IsWritableProperty< TProperty >::value, Delegate< void(DynamicObject &, typename TProperty::TSetterParam)> >::type
获取属性的Setter委托
Definition Reflection.h:1072
static FieldId GetFieldId(TField T::*field) noexcept
获取字段的唯一标识符
Definition Reflection.h:961
static auto GetPropertyGetter(TProperty T::*prop) -> typename std::enable_if< _IsReadableProperty< TProperty >::value, Delegate< typename TProperty::TValue(DynamicObject &)> >::type
获取属性的Getter委托
Definition Reflection.h:1036
表示字段的唯一标识符
Definition Reflection.h:898
判断类型是否为属性的辅助模板
Definition Property.h:95