SimpleWindow
载入中...
搜索中...
未找到
Binding.h
1#pragma once
2
3#include "BindingCastHelper.h"
4#include "INotifyObjectDead.h"
5#include "INotifyPropertyChanged.h"
6#include "IValueConverter.h"
7
8namespace sw
9{
13 enum class BindingMode {
15 OneTime,
16
18 OneWay,
19
22
24 TwoWay,
25 };
26
31 {
32 public:
36 virtual ~BindingBase() = default;
37
38 public:
43 virtual bool UpdateTarget() = 0;
44
49 virtual bool UpdateSource() = 0;
50
54 virtual FieldId GetTargetPropertyId() const = 0;
55
59 virtual FieldId GetSourcePropertyId() const = 0;
60 };
61
65 class Binding final : public BindingBase
66 {
67 private:
71 BindingMode _mode;
72
76 DynamicObject *_targetObject;
77
81 DynamicObject *_sourceObject;
82
86 FieldId _targetPropertyId;
87
91 FieldId _sourcePropertyId;
92
96 void *_converter;
97
101 void (*_converterDeleter)(void *);
102
106 Func<Binding *, bool> _updateTargetFunc;
107
111 Func<Binding *, bool> _updateSourceFunc;
112
113 private:
117 Binding() = default;
118
119 // 删除拷贝构造函数
120 Binding(const Binding &) = delete;
121
122 // 删除移动构造函数
123 Binding(Binding &&) = delete;
124
125 // 删除拷贝赋值运算符
126 Binding &operator=(const Binding &) = delete;
127
128 // 删除移动赋值运算符
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
192 {
193 return _mode;
194 }
195
200 {
201 return _targetObject;
202 }
203
208 {
209 return _sourceObject;
210 }
211
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, PropertyChangedEventArgs &e)
330 {
331 if (e.propertyId != _targetPropertyId) {
332 return;
333 }
334
335 if (_mode == BindingMode::TwoWay ||
337 UpdateSource();
338 }
339 }
340
344 void OnSourcePropertyChanged(INotifyPropertyChanged &sender, PropertyChangedEventArgs &e)
345 {
346 if (e.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, EventArgs &e)
360 {
361 SetTargetObject(nullptr);
362 }
363
367 void OnSourceObjectDead(INotifyObjectDead &sender, EventArgs &e)
368 {
369 SetSourceObject(nullptr);
370 }
371
375 void OnBindingChanged()
376 {
377 switch (_mode) {
380 case BindingMode::TwoWay: {
381 UpdateTarget();
382 break;
383 }
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>
443 -> typename std::enable_if<
446 std::is_base_of<DynamicObject, TTargetObject>::value &&
447 std::is_base_of<DynamicObject, TSourceObject>::value &&
449 Binding *>::type
450 {
451 using TTargetValue = typename TTargetProperty::TValue;
452 using TSourceValue = typename TSourceProperty::TValue;
454
455 auto binding = Create(
458
459 // update target action
462 {
464 reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(binding->_converter);
465
466 if (targetSetter == nullptr ||
467 sourceGetter == nullptr ||
468 binding->_targetObject == nullptr ||
469 binding->_sourceObject == nullptr) {
470 return false;
471 }
472
473 if (converter) {
475 *binding->_targetObject,
476 converter->Convert(sourceGetter(*binding->_sourceObject)));
477 } else {
479 *binding->_targetObject,
480 DefaultCaster::Convert(sourceGetter(*binding->_sourceObject)));
481 }
482 return true;
483 };
484
485 // update source action
488 {
490 reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(binding->_converter);
491
492 if (targetGetter == nullptr ||
493 sourceSetter == nullptr ||
494 binding->_targetObject == nullptr ||
495 binding->_sourceObject == nullptr) {
496 return false;
497 }
498
499 if (converter) {
501 *binding->_sourceObject,
502 converter->ConvertBack(targetGetter(*binding->_targetObject)));
503 } else {
505 *binding->_sourceObject,
506 DefaultCaster::ConvertBack(targetGetter(*binding->_targetObject)));
507 }
508 return true;
509 };
510
511 binding->RegisterNotifications();
512 binding->OnBindingChanged();
513 return binding;
514 }
515
526 template <
527 typename TTargetObject,
528 typename TTargetProperty,
529 typename TSourceObject,
530 typename TSourceProperty>
546
556 template <
557 typename TTargetObject,
558 typename TTargetProperty,
559 typename TSourceObject,
560 typename TSourceProperty>
575
587 template <
588 typename TTargetObject,
589 typename TTargetProperty,
590 typename TSourceObject,
591 typename TSourceProperty>
596 -> typename std::enable_if<
599 std::is_base_of<DynamicObject, TTargetObject>::value &&
600 std::is_base_of<DynamicObject, TSourceObject>::value &&
602 Binding *>::type
603 {
604 using TTargetValue = typename TTargetProperty::TValue;
605 using TSourceValue = typename TSourceProperty::TValue;
606
607 auto binding = Create(
610
611 // update target action
614 {
616 reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(binding->_converter);
617
618 if (targetSetter == nullptr ||
619 sourceGetter == nullptr ||
620 converter == nullptr ||
621 binding->_targetObject == nullptr ||
622 binding->_sourceObject == nullptr) {
623 return false;
624 }
625
627 *binding->_targetObject,
628 converter->Convert(sourceGetter(*binding->_sourceObject)));
629 return true;
630 };
631
632 // update source action
635 {
637 reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(binding->_converter);
638
639 if (targetGetter == nullptr ||
640 sourceSetter == nullptr ||
641 converter == nullptr ||
642 binding->_targetObject == nullptr ||
643 binding->_sourceObject == nullptr) {
644 return false;
645 }
646
648 *binding->_sourceObject,
649 converter->ConvertBack(targetGetter(*binding->_targetObject)));
650 return true;
651 };
652
653 binding->RegisterNotifications();
654 binding->OnBindingChanged();
655 return binding;
656 }
657
668 template <
669 typename TTargetObject,
670 typename TTargetProperty,
671 typename TSourceObject,
672 typename TSourceProperty>
688
698 template <
699 typename TTargetObject,
700 typename TTargetProperty,
701 typename TSourceObject,
702 typename TSourceProperty>
717 };
718}
数据绑定基类
Definition Binding.h:31
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:66
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 &&!BindingCastHelper< typename TSourceProperty::TValue, typename TTargetProperty::TValue >::value, Binding * >::type
创建绑定对象
Definition Binding.h:592
void SetBindingObjects(DynamicObject *target, DynamicObject *source)
修改目标对象和源对象
Definition Binding.h:252
void SetBindingMode(BindingMode mode)
修改绑定模式
Definition Binding.h:215
BindingMode GetBindingMode() const
获取绑定模式
Definition Binding.h:191
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 &&BindingCastHelper< typename TSourceProperty::TValue, typename TTargetProperty::TValue >::value, Binding * >::type
创建延迟绑定对象
Definition Binding.h:531
DynamicObject * GetTargetObject() const
获取目标对象
Definition Binding.h:199
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 &&BindingCastHelper< typename TSourceProperty::TValue, typename TTargetProperty::TValue >::value, Binding * >::type
创建延迟绑定对象
Definition Binding.h:561
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
virtual FieldId GetSourcePropertyId() const override
获取源属性ID
Definition Binding.h:183
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 &&BindingCastHelper< typename TSourceProperty::TValue, typename TTargetProperty::TValue >::value, Binding * >::type
创建绑定对象
Definition Binding.h:439
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 &&!BindingCastHelper< typename TSourceProperty::TValue, typename TTargetProperty::TValue >::value, Binding * >::type
创建延迟绑定对象
Definition Binding.h:703
void SetTargetObject(DynamicObject *target)
修改目标对象
Definition Binding.h:226
void SetSourceObject(DynamicObject *source)
修改源对象
Definition Binding.h:239
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 &&!BindingCastHelper< typename TSourceProperty::TValue, typename TTargetProperty::TValue >::value, Binding * >::type
创建延迟绑定对象
Definition Binding.h:673
动态对象基类
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:105
属性变更通知接口
Definition INotifyPropertyChanged.h:30
const Event< PropertyChangedEventHandler > PropertyChanged
当属性值更改时触发的事件
Definition INotifyPropertyChanged.h:35
值转换器接口
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:1341
static FieldId GetFieldId(TField T::*field) noexcept
获取字段的唯一标识符
Definition Reflection.h:1230
static auto GetPropertyGetter(TProperty T::*prop) -> typename std::enable_if< _IsReadableProperty< TProperty >::value, Delegate< typename TProperty::TValue(DynamicObject &)> >::type
获取属性的Getter委托
Definition Reflection.h:1305
SimpleWindow框架的顶级命名空间,所有公共类型、控件、枚举和工具函数均定义于此。
Definition Alignment.h:4
typename _FuncTypeHelper< typename _FuncTraits< Types... >::TArgsTuple >::template TFunc< typename _FuncTraits< Types... >::TRet > Func
Func类型别名,类似C::中的Func<T1, T2, ..., TResult>
Definition Delegate.h:1175
EventHandler< INotifyObjectDead > ObjectDeadEventHandler
对象销毁事件处理程序类型
Definition INotifyObjectDead.h:14
BindingMode
绑定模式枚举
Definition Binding.h:13
@ OneWayToSource
单向,从目标到源
@ TwoWay
双向,源和目标相互更新
@ OneWay
单向,从源到目标
@ OneTime
一次性绑定,在绑定创建时更新目标属性值
EventHandler< INotifyPropertyChanged, PropertyChangedEventArgs > PropertyChangedEventHandler
属性更改事件处理函数类型
Definition INotifyPropertyChanged.h:24
Binding默认转换辅助模板
Definition BindingCastHelper.h:20
表示字段的唯一标识符
Definition Reflection.h:1167
判断类型是否为属性的辅助模板
Definition Property.h:95