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 {
14 OneTime,
15
17 OneWay,
18
21
23 TwoWay,
24 };
25
30 {
31 public:
35 virtual ~BindingBase() = default;
36
37 public:
42 virtual bool UpdateTarget() = 0;
43
48 virtual bool UpdateSource() = 0;
49
53 virtual FieldId GetTargetPropertyId() const = 0;
54
58 virtual FieldId GetSourcePropertyId() const = 0;
59 };
60
64 class Binding final : public BindingBase
65 {
66 private:
70 BindingMode _mode;
71
75 DynamicObject *_targetObject;
76
80 DynamicObject *_sourceObject;
81
85 FieldId _targetPropertyId;
86
90 FieldId _sourcePropertyId;
91
95 void *_converter;
96
100 void (*_converterDeleter)(void *);
101
105 Func<Binding *, bool> _updateTargetFunc;
106
110 Func<Binding *, bool> _updateSourceFunc;
111
112 private:
116 Binding() = default;
117
118 Binding(const Binding &) = delete; // 删除拷贝构造函数
119 Binding(Binding &&) = delete; // 删除移动构造函数
120 Binding &operator=(const Binding &) = delete; // 删除拷贝赋值运算符
121 Binding &operator=(Binding &&) = delete; // 删除移动赋值运算符
122
123 public:
127 virtual ~Binding()
128 {
129 UnregisterNotifications();
130
131 if (_converterDeleter && _converter) {
132 _converterDeleter(_converter);
133 }
134 }
135
140 virtual bool UpdateTarget() override
141 {
142 bool result = false;
143
144 if (_updateTargetFunc) {
145 result = _updateTargetFunc(this);
146 }
147 return result;
148 }
149
154 virtual bool UpdateSource() override
155 {
156 bool result = false;
157
158 if (_updateSourceFunc) {
159 result = _updateSourceFunc(this);
160 }
161 return result;
162 }
163
167 virtual FieldId GetTargetPropertyId() const override
168 {
169 return _targetPropertyId;
170 }
171
175 virtual FieldId GetSourcePropertyId() const override
176 {
177 return _sourcePropertyId;
178 }
179
184 {
185 return _mode;
186 }
187
192 {
193 return _targetObject;
194 }
195
200 {
201 return _sourceObject;
202 }
203
208 {
209 if (_mode != mode) {
210 _mode = mode;
211 OnBindingChanged();
212 }
213 }
214
219 {
220 if (_targetObject != target) {
221 UnregisterNotifications();
222 _targetObject = target;
223 RegisterNotifications();
224 OnBindingChanged();
225 }
226 }
227
232 {
233 if (_sourceObject != source) {
234 UnregisterNotifications();
235 _sourceObject = source;
236 RegisterNotifications();
237 OnBindingChanged();
238 }
239 }
240
245 {
246 if (_targetObject != target ||
247 _sourceObject != source) //
248 {
249 UnregisterNotifications();
250 _targetObject = target;
251 _sourceObject = source;
252 RegisterNotifications();
253 OnBindingChanged();
254 }
255 }
256
257 private:
261 void RegisterNotifications()
262 {
263 INotifyPropertyChanged *targetNotifObj = nullptr;
264 INotifyPropertyChanged *sourceNotifObj = nullptr;
265
266 if (_targetObject != nullptr && _targetObject->IsType(&targetNotifObj)) {
267 targetNotifObj->PropertyChanged +=
268 PropertyChangedEventHandler(*this, &Binding::OnTargetPropertyChanged);
269 }
270 if (_sourceObject != nullptr && _sourceObject->IsType(&sourceNotifObj)) {
271 sourceNotifObj->PropertyChanged +=
272 PropertyChangedEventHandler(*this, &Binding::OnSourcePropertyChanged);
273 }
274
275 INotifyObjectDead *targetNotifObjDead = nullptr;
276 INotifyObjectDead *sourceNotifObjDead = nullptr;
277
278 if (_targetObject != nullptr && _targetObject->IsType(&targetNotifObjDead)) {
279 targetNotifObjDead->ObjectDead +=
280 ObjectDeadEventHandler(*this, &Binding::OnTargetObjectDead);
281 }
282 if (_sourceObject != nullptr && _sourceObject->IsType(&sourceNotifObjDead)) {
283 sourceNotifObjDead->ObjectDead +=
284 ObjectDeadEventHandler(*this, &Binding::OnSourceObjectDead);
285 }
286 }
287
291 void UnregisterNotifications()
292 {
293 INotifyPropertyChanged *targetNotifObj = nullptr;
294 INotifyPropertyChanged *sourceNotifObj = nullptr;
295
296 if (_targetObject != nullptr && _targetObject->IsType(&targetNotifObj)) {
297 targetNotifObj->PropertyChanged -=
298 PropertyChangedEventHandler(*this, &Binding::OnTargetPropertyChanged);
299 }
300 if (_sourceObject != nullptr && _sourceObject->IsType(&sourceNotifObj)) {
301 sourceNotifObj->PropertyChanged -=
302 PropertyChangedEventHandler(*this, &Binding::OnSourcePropertyChanged);
303 }
304
305 INotifyObjectDead *targetNotifObjDead = nullptr;
306 INotifyObjectDead *sourceNotifObjDead = nullptr;
307
308 if (_targetObject != nullptr && _targetObject->IsType(&targetNotifObjDead)) {
309 targetNotifObjDead->ObjectDead -=
310 ObjectDeadEventHandler(*this, &Binding::OnTargetObjectDead);
311 }
312 if (_sourceObject != nullptr && _sourceObject->IsType(&sourceNotifObjDead)) {
313 sourceNotifObjDead->ObjectDead -=
314 ObjectDeadEventHandler(*this, &Binding::OnSourceObjectDead);
315 }
316 }
317
321 void OnTargetPropertyChanged(INotifyPropertyChanged &sender, PropertyChangedEventArgs &e)
322 {
323 if (e.propertyId != _targetPropertyId) {
324 return;
325 }
326
327 if (_mode == BindingMode::TwoWay ||
329 UpdateSource();
330 }
331 }
332
336 void OnSourcePropertyChanged(INotifyPropertyChanged &sender, PropertyChangedEventArgs &e)
337 {
338 if (e.propertyId != _sourcePropertyId) {
339 return;
340 }
341
342 if (_mode == BindingMode::TwoWay ||
343 _mode == BindingMode::OneWay) {
344 UpdateTarget();
345 }
346 }
347
351 void OnTargetObjectDead(INotifyObjectDead &sender, EventArgs &e)
352 {
353 SetTargetObject(nullptr);
354 }
355
359 void OnSourceObjectDead(INotifyObjectDead &sender, EventArgs &e)
360 {
361 SetSourceObject(nullptr);
362 }
363
367 void OnBindingChanged()
368 {
369 switch (_mode) {
372 case BindingMode::TwoWay: {
373 UpdateTarget();
374 break;
375 }
377 UpdateSource();
378 break;
379 }
380 }
381 }
382
393 template <typename TTargetValue, typename TSourceValue>
394 static Binding *Create(DynamicObject *target, FieldId targetPropertyId,
395 DynamicObject *source, FieldId sourcePropertyId,
396 BindingMode mode, IValueConverter<TSourceValue, TTargetValue> *converter)
397 {
398 auto binding = new Binding;
399
400 binding->_targetObject = target;
401 binding->_sourceObject = source;
402 binding->_targetPropertyId = targetPropertyId;
403 binding->_sourcePropertyId = sourcePropertyId;
404
405 binding->_mode = mode;
406 binding->_converter = converter;
407
408 binding->_converterDeleter = [](void *ptr) {
409 delete reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(ptr);
410 };
411 return binding;
412 }
413
414 public:
426 template <
427 typename TTargetObject,
428 typename TTargetProperty,
429 typename TSourceObject,
430 typename TSourceProperty>
435 -> typename std::enable_if<
438 std::is_base_of<DynamicObject, TTargetObject>::value &&
439 std::is_base_of<DynamicObject, TSourceObject>::value &&
440 std::is_same<typename TTargetProperty::TValue, typename TSourceProperty::TValue>::value,
441 Binding *>::type
442 {
443 using TTargetValue = typename TTargetProperty::TValue;
444 using TSourceValue = typename TSourceProperty::TValue;
445
446 auto binding = Create(
449
450 // update target action
453 {
455 reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(binding->_converter);
456
457 if (targetSetter == nullptr ||
458 sourceGetter == nullptr ||
459 binding->_targetObject == nullptr ||
460 binding->_sourceObject == nullptr) {
461 return false;
462 }
463
464 if (converter) {
466 *binding->_targetObject,
467 converter->Convert(sourceGetter(*binding->_sourceObject)));
468 } else {
470 *binding->_targetObject,
471 sourceGetter(*binding->_sourceObject));
472 }
473 return true;
474 };
475
476 // update source action
479 {
481 reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(binding->_converter);
482
483 if (targetGetter == nullptr ||
484 sourceSetter == nullptr ||
485 binding->_targetObject == nullptr ||
486 binding->_sourceObject == nullptr) {
487 return false;
488 }
489
490 if (converter) {
492 *binding->_sourceObject,
493 converter->ConvertBack(targetGetter(*binding->_targetObject)));
494 } else {
496 *binding->_sourceObject,
497 targetGetter(*binding->_targetObject));
498 }
499 return true;
500 };
501
502 binding->RegisterNotifications();
503 binding->OnBindingChanged();
504 return binding;
505 }
506
517 template <
518 typename TTargetObject,
519 typename TTargetProperty,
520 typename TSourceObject,
521 typename TSourceProperty>
537
547 template <
548 typename TTargetObject,
549 typename TTargetProperty,
550 typename TSourceObject,
551 typename TSourceProperty>
566
578 template <
579 typename TTargetObject,
580 typename TTargetProperty,
581 typename TSourceObject,
582 typename TSourceProperty>
587 -> typename std::enable_if<
590 std::is_base_of<DynamicObject, TTargetObject>::value &&
591 std::is_base_of<DynamicObject, TSourceObject>::value &&
592 !std::is_same<typename TTargetProperty::TValue, typename TSourceProperty::TValue>::value,
593 Binding *>::type
594 {
595 using TTargetValue = typename TTargetProperty::TValue;
596 using TSourceValue = typename TSourceProperty::TValue;
597
598 auto binding = Create(
601
602 // update target action
605 {
607 reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(binding->_converter);
608
609 if (targetSetter == nullptr ||
610 sourceGetter == nullptr ||
611 converter == nullptr ||
612 binding->_targetObject == nullptr ||
613 binding->_sourceObject == nullptr) {
614 return false;
615 }
616
618 *binding->_targetObject,
619 converter->Convert(sourceGetter(*binding->_sourceObject)));
620 return true;
621 };
622
623 // update source action
626 {
628 reinterpret_cast<IValueConverter<TSourceValue, TTargetValue> *>(binding->_converter);
629
630 if (targetGetter == nullptr ||
631 sourceSetter == nullptr ||
632 converter == nullptr ||
633 binding->_targetObject == nullptr ||
634 binding->_sourceObject == nullptr) {
635 return false;
636 }
637
639 *binding->_sourceObject,
640 converter->ConvertBack(targetGetter(*binding->_targetObject)));
641 return true;
642 };
643
644 binding->RegisterNotifications();
645 binding->OnBindingChanged();
646 return binding;
647 }
648
659 template <
660 typename TTargetObject,
661 typename TTargetProperty,
662 typename TSourceObject,
663 typename TSourceProperty>
679
689 template <
690 typename TTargetObject,
691 typename TTargetProperty,
692 typename TSourceObject,
693 typename TSourceProperty>
708 };
709}
数据绑定基类
Definition Binding.h:30
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:65
void SetBindingObjects(DynamicObject *target, DynamicObject *source)
修改目标对象和源对象
Definition Binding.h:244
void SetBindingMode(BindingMode mode)
修改绑定模式
Definition Binding.h:207
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:431
BindingMode GetBindingMode() const
获取绑定模式
Definition Binding.h:183
DynamicObject * GetTargetObject() const
获取目标对象
Definition Binding.h:191
virtual bool UpdateSource() override
更新源属性的值
Definition Binding.h:154
virtual FieldId GetTargetPropertyId() const override
获取目标属性ID
Definition Binding.h:167
virtual bool UpdateTarget() override
更新目标属性的值
Definition Binding.h:140
DynamicObject * GetSourceObject() const
获取源对象
Definition Binding.h:199
virtual ~Binding()
析构函数
Definition Binding.h:127
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:694
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:583
virtual FieldId GetSourcePropertyId() const override
获取源属性ID
Definition Binding.h:175
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:522
void SetTargetObject(DynamicObject *target)
修改目标对象
Definition Binding.h:218
void SetSourceObject(DynamicObject *source)
修改源对象
Definition Binding.h:231
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:552
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:664
动态对象基类
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: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:1194
static FieldId GetFieldId(TField T::*field) noexcept
获取字段的唯一标识符
Definition Reflection.h:1083
static auto GetPropertyGetter(TProperty T::*prop) -> typename std::enable_if< _IsReadableProperty< TProperty >::value, Delegate< typename TProperty::TValue(DynamicObject &)> >::type
获取属性的Getter委托
Definition Reflection.h:1158
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:1124
EventHandler< INotifyObjectDead > ObjectDeadEventHandler
对象销毁事件处理程序类型
Definition INotifyObjectDead.h:14
BindingMode
绑定模式枚举
Definition Binding.h:12
@ OneWayToSource
单向,从目标到源
@ TwoWay
双向,源和目标相互更新
@ OneWay
单向,从源到目标
@ OneTime
一次性绑定,在绑定创建时更新目标属性值
EventHandler< INotifyPropertyChanged, PropertyChangedEventArgs > PropertyChangedEventHandler
属性更改事件处理函数类型
Definition INotifyPropertyChanged.h:24
表示字段的唯一标识符
Definition Reflection.h:1020
判断类型是否为属性的辅助模板
Definition Property.h:95