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
391 public:
403 template <
404 typename TTargetObject,
405 typename TTargetProperty,
406 typename TSourceObject,
407 typename TSourceProperty>
408 static auto Create(DynamicObject *target, TTargetProperty TTargetObject::*targetProperty,
409 DynamicObject *source, TSourceProperty TSourceObject::*sourceProperty,
410 BindingMode mode,
411 IValueConverter<typename TSourceProperty::TValue, typename TTargetProperty::TValue> *converter = nullptr)
412 -> typename std::enable_if<
413 _IsProperty<TTargetProperty>::value &&
414 _IsProperty<TSourceProperty>::value &&
415 std::is_base_of<DynamicObject, TTargetObject>::value &&
416 std::is_base_of<DynamicObject, TSourceObject>::value &&
417 std::is_same<typename TTargetProperty::TValue, typename TSourceProperty::TValue>::value,
418 Binding *>::type
419 {
420 using TTargetValue = typename TTargetProperty::TValue;
421 using TSourceValue = typename TSourceProperty::TValue;
422
423 auto binding = new Binding;
424 binding->_mode = mode;
425
426 binding->_targetObject = target;
427 binding->_sourceObject = source;
428 binding->_targetPropertyId = Reflection::GetFieldId(targetProperty);
429 binding->_sourcePropertyId = Reflection::GetFieldId(sourceProperty);
430
431 binding->_converter = converter;
432 binding->_converterDeleter = [](void *ptr) {
433 delete reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(ptr);
434 };
435
436 // update target action
437 binding->_updateTargetFunc = [targetSetter = Reflection::GetPropertySetter(targetProperty),
438 sourceGetter = Reflection::GetPropertyGetter(sourceProperty)](Binding *binding) -> bool //
439 {
441 reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(binding->_converter);
442
443 if (targetSetter == nullptr ||
444 sourceGetter == nullptr ||
445 binding->_targetObject == nullptr ||
446 binding->_sourceObject == nullptr) {
447 return false;
448 }
449
450 if (converter) {
451 targetSetter(
452 *binding->_targetObject,
453 converter->Convert(sourceGetter(*binding->_sourceObject)));
454 } else {
455 targetSetter(
456 *binding->_targetObject,
457 sourceGetter(*binding->_sourceObject));
458 }
459 return true;
460 };
461
462 // update source action
463 binding->_updateSourceFunc = [targetGetter = Reflection::GetPropertyGetter(targetProperty),
464 sourceSetter = Reflection::GetPropertySetter(sourceProperty)](Binding *binding) -> bool //
465 {
467 reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(binding->_converter);
468
469 if (targetGetter == nullptr ||
470 sourceSetter == nullptr ||
471 binding->_targetObject == nullptr ||
472 binding->_sourceObject == nullptr) {
473 return false;
474 }
475
476 if (converter) {
477 sourceSetter(
478 *binding->_sourceObject,
479 converter->ConvertBack(targetGetter(*binding->_targetObject)));
480 } else {
481 sourceSetter(
482 *binding->_sourceObject,
483 targetGetter(*binding->_targetObject));
484 }
485 return true;
486 };
487
488 binding->RegisterNotifications();
489 binding->OnBindingChanged();
490 return binding;
491 }
492
503 template <
504 typename TTargetObject,
505 typename TTargetProperty,
506 typename TSourceObject,
507 typename TSourceProperty>
508 static auto Create(TTargetProperty TTargetObject::*targetProperty,
509 DynamicObject *source,
510 TSourceProperty TSourceObject::*sourceProperty,
511 BindingMode mode,
512 IValueConverter<typename TSourceProperty::TValue, typename TTargetProperty::TValue> *converter = nullptr)
513 -> typename std::enable_if<
514 _IsProperty<TTargetProperty>::value &&
515 _IsProperty<TSourceProperty>::value &&
516 std::is_base_of<DynamicObject, TTargetObject>::value &&
517 std::is_base_of<DynamicObject, TSourceObject>::value &&
518 std::is_same<typename TTargetProperty::TValue, typename TSourceProperty::TValue>::value,
519 Binding *>::type
520 {
521 return Create(nullptr, targetProperty, source, sourceProperty, mode, converter);
522 }
523
533 template <
534 typename TTargetObject,
535 typename TTargetProperty,
536 typename TSourceObject,
537 typename TSourceProperty>
538 static auto Create(TTargetProperty TTargetObject::*targetProperty,
539 TSourceProperty TSourceObject::*sourceProperty,
540 BindingMode mode,
541 IValueConverter<typename TSourceProperty::TValue, typename TTargetProperty::TValue> *converter = nullptr)
542 -> typename std::enable_if<
543 _IsProperty<TTargetProperty>::value &&
544 _IsProperty<TSourceProperty>::value &&
545 std::is_base_of<DynamicObject, TTargetObject>::value &&
546 std::is_base_of<DynamicObject, TSourceObject>::value &&
547 std::is_same<typename TTargetProperty::TValue, typename TSourceProperty::TValue>::value,
548 Binding *>::type
549 {
550 return Create(nullptr, targetProperty, nullptr, sourceProperty, mode, converter);
551 }
552
564 template <
565 typename TTargetObject,
566 typename TTargetProperty,
567 typename TSourceObject,
568 typename TSourceProperty>
569 static auto Create(DynamicObject *target, TTargetProperty TTargetObject::*targetProperty,
570 DynamicObject *source, TSourceProperty TSourceObject::*sourceProperty,
571 BindingMode mode,
572 IValueConverter<typename TSourceProperty::TValue, typename TTargetProperty::TValue> *converter)
573 -> typename std::enable_if<
574 _IsProperty<TTargetProperty>::value &&
575 _IsProperty<TSourceProperty>::value &&
576 std::is_base_of<DynamicObject, TTargetObject>::value &&
577 std::is_base_of<DynamicObject, TSourceObject>::value &&
578 !std::is_same<typename TTargetProperty::TValue, typename TSourceProperty::TValue>::value,
579 Binding *>::type
580 {
581 using TTargetValue = typename TTargetProperty::TValue;
582 using TSourceValue = typename TSourceProperty::TValue;
583
584 auto binding = new Binding;
585 binding->_mode = mode;
586
587 binding->_targetObject = target;
588 binding->_sourceObject = source;
589 binding->_targetPropertyId = Reflection::GetFieldId(targetProperty);
590 binding->_sourcePropertyId = Reflection::GetFieldId(sourceProperty);
591
592 binding->_converter = converter;
593 binding->_converterDeleter = [](void *ptr) {
594 delete reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(ptr);
595 };
596
597 // update target action
598 binding->_updateTargetFunc = [targetSetter = Reflection::GetPropertySetter(targetProperty),
599 sourceGetter = Reflection::GetPropertyGetter(sourceProperty)](Binding *binding) -> bool //
600 {
602 reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(binding->_converter);
603
604 if (targetSetter == nullptr ||
605 sourceGetter == nullptr ||
606 converter == nullptr ||
607 binding->_targetObject == nullptr ||
608 binding->_sourceObject == nullptr) {
609 return false;
610 }
611
612 targetSetter(
613 *binding->_targetObject,
614 converter->Convert(sourceGetter(*binding->_sourceObject)));
615 return true;
616 };
617
618 // update source action
619 binding->_updateSourceFunc = [targetGetter = Reflection::GetPropertyGetter(targetProperty),
620 sourceSetter = Reflection::GetPropertySetter(sourceProperty)](Binding *binding) -> bool //
621 {
623 reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(binding->_converter);
624
625 if (targetGetter == nullptr ||
626 sourceSetter == nullptr ||
627 converter == nullptr ||
628 binding->_targetObject == nullptr ||
629 binding->_sourceObject == nullptr) {
630 return false;
631 }
632
633 sourceSetter(
634 *binding->_sourceObject,
635 converter->ConvertBack(targetGetter(*binding->_targetObject)));
636 return true;
637 };
638
639 binding->RegisterNotifications();
640 binding->OnBindingChanged();
641 return binding;
642 }
643
654 template <
655 typename TTargetObject,
656 typename TTargetProperty,
657 typename TSourceObject,
658 typename TSourceProperty>
659 static auto Create(TTargetProperty TTargetObject::*targetProperty,
660 DynamicObject *source,
661 TSourceProperty TSourceObject::*sourceProperty,
662 BindingMode mode,
663 IValueConverter<typename TSourceProperty::TValue, typename TTargetProperty::TValue> *converter)
664 -> typename std::enable_if<
665 _IsProperty<TTargetProperty>::value &&
666 _IsProperty<TSourceProperty>::value &&
667 std::is_base_of<DynamicObject, TTargetObject>::value &&
668 std::is_base_of<DynamicObject, TSourceObject>::value &&
669 !std::is_same<typename TTargetProperty::TValue, typename TSourceProperty::TValue>::value,
670 Binding *>::type
671 {
672 return Create(nullptr, targetProperty, source, sourceProperty, mode, converter);
673 }
674
684 template <
685 typename TTargetObject,
686 typename TTargetProperty,
687 typename TSourceObject,
688 typename TSourceProperty>
689 static auto Create(TTargetProperty TTargetObject::*targetProperty,
690 TSourceProperty TSourceObject::*sourceProperty,
691 BindingMode mode,
692 IValueConverter<typename TSourceProperty::TValue, typename TTargetProperty::TValue> *converter)
693 -> typename std::enable_if<
694 _IsProperty<TTargetProperty>::value &&
695 _IsProperty<TSourceProperty>::value &&
696 std::is_base_of<DynamicObject, TTargetObject>::value &&
697 std::is_base_of<DynamicObject, TSourceObject>::value &&
698 !std::is_same<typename TTargetProperty::TValue, typename TSourceProperty::TValue>::value,
699 Binding *>::type
700 {
701 return Create(nullptr, targetProperty, nullptr, sourceProperty, mode, converter);
702 }
703 };
704}
数据绑定基类
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:408
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:689
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:569
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:508
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:538
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:659
Definition Delegate.h:21
动态对象基类
Definition Reflection.h:26
bool IsType(T **pout=nullptr)
判断对象是否为指定类型
Definition Reflection.h:53
属性变更通知接口
Definition INotifyPropertyChanged.h:18
PropertyChangedEventHandler PropertyChanged
当属性值更改时触发的事件
Definition INotifyPropertyChanged.h:23
值转换器接口
Definition IValueConverter.h:20
virtual TTarget Convert(TSourceParam source)=0
将源类型转换为目标类型
virtual TSource ConvertBack(TTargetParam target)=0
将目标类型转换为源类型
static FieldId GetFieldId(TField T::*field) noexcept
获取字段的唯一标识符
Definition Reflection.h:237
static auto GetPropertySetter(TProperty T::*prop) -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value &&_IsWritableProperty< TProperty >::value, Delegate< void(DynamicObject &, typename TProperty::TSetterParam)> >::type
获取属性的Setter委托
Definition Reflection.h:354
static auto GetPropertyGetter(TProperty T::*prop) -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value &&_IsReadableProperty< TProperty >::value, Delegate< typename TProperty::TValue(DynamicObject &)> >::type
获取属性的Getter委托
Definition Reflection.h:318
表示字段的唯一标识符
Definition Reflection.h:177
判断类型是否为属性的辅助模板
Definition Property.h:94