1#if !NETFX_CORE && !XAMARIN
10using System.Collections.ObjectModel;
11using System.ComponentModel;
14using System.Windows.Controls;
15using System.Windows.Controls.Primitives;
16using System.Windows.Input;
17using System.Windows.Media;
30 [TemplatePart(Name =
"image", Type = typeof(FrameworkElement))]
31 [TemplatePart(Name =
"popup", Type = typeof(Popup))]
32 [TemplatePart(Name =
"busy", Type = typeof(BusyAnimation))]
33 [TemplateVisualState(Name =
"PropertyValid", GroupName =
"CommonStates")]
34 [TemplateVisualState(Name =
"Error", GroupName =
"CommonStates")]
35 [TemplateVisualState(Name =
"Warning", GroupName =
"CommonStates")]
36 [TemplateVisualState(Name =
"Information", GroupName =
"CommonStates")]
39 private bool _isReadOnly =
false;
40 private FrameworkElement _lastImage;
41 private Point _lastPosition;
42 private Point _popupLastPosition;
43 private Size _lastAppSize;
44 private Size _lastPopupSize;
67 private bool _loading =
true;
75 BrokenRules =
new ObservableCollection<BrokenRule>();
88 IsVisibleChanged += (o, e) =>
92 if (!_loading && IsVisible)
97 DataContextChanged += (o, e) =>
108 base.OnApplyTemplate();
114#region Source property
124 new PropertyMetadata(
new object(), (o, e) =>
127 if (e.NewValue ==
null)
129 if (e.OldValue == null)
132 else if (e.NewValue.Equals(e.OldValue))
150 private object _source =
null;
167 private string _bindingPath =
string.Empty;
180 _bindingPath = value;
184 private string _propertyName =
string.Empty;
194 get {
return _propertyName; }
195 set { _propertyName = value; }
201 protected virtual void SetSource(
bool propertyValueChanged)
219 if (!ReferenceEquals(
Source, newSource))
237 private void SetBindingValues()
239 var bindingPath =
string.Empty;
240 var propertyName =
string.Empty;
245 if (binding.ParentBinding !=
null && binding.ParentBinding.Path !=
null)
246 bindingPath = binding.ParentBinding.Path.Path;
248 bindingPath =
string.Empty;
249 propertyName = (bindingPath.IndexOf(
'.') > 0)
250 ? bindingPath.Substring(bindingPath.LastIndexOf(
'.') + 1)
266 var firstProperty =
string.Empty;
267 if (bindingPath.IndexOf(
'.') > 0)
268 firstProperty = bindingPath.Substring(0, bindingPath.IndexOf(
'.'));
270 var icv = source as ICollectionView;
271 if (icv !=
null && firstProperty !=
"CurrentItem")
272 source = icv.CurrentItem;
273 if (source !=
null && !
string.IsNullOrEmpty(firstProperty))
275 var p = MethodCaller.GetProperty(source.GetType(), firstProperty);
277 MethodCaller.GetPropertyValue(source, p),
278 bindingPath.Substring(bindingPath.IndexOf(
'.') + 1));
284 private void DetachSource(
object source)
286 var p = source as INotifyPropertyChanged;
288 p.PropertyChanged -= source_PropertyChanged;
296 private void AttachSource(
object source)
298 var p = source as INotifyPropertyChanged;
300 p.PropertyChanged += source_PropertyChanged;
307 void source_PropertyChanged(
object sender, PropertyChangedEventArgs e)
309 if (e.PropertyName ==
PropertyName ||
string.IsNullOrEmpty(e.PropertyName))
332#region BrokenRules property
340 typeof(ObservableCollection<BrokenRule>),
348 [Category(
"Property Status")]
357#region State properties
359 private bool _canRead =
true;
364 [Category(
"Property Status")]
367 get {
return _canRead; }
370 if (value != _canRead)
378 private bool _canWrite =
true;
383 [Category(
"Property Status")]
386 get {
return _canWrite; }
389 if (value != _canWrite)
397 private bool _isBusy =
false;
402 [Category(
"Property Status")]
405 get {
return _isBusy; }
408 if (value != _isBusy)
416 private bool _isValid =
true;
421 [Category(
"Property Status")]
424 get {
return _isValid; }
427 if (value != _isValid)
442 [Category(
"Property Status")]
445 get {
return _worst; }
456 private string _ruleDescription =
string.Empty;
461 [Category(
"Property Status")]
464 get {
return _ruleDescription; }
467 if (value != _ruleDescription)
469 _ruleDescription = value;
479 private void EnablePopup(FrameworkElement image)
483 image.MouseEnter +=
new MouseEventHandler(image_MouseEnter);
484 image.MouseLeave +=
new MouseEventHandler(image_MouseLeave);
488 private void DisablePopup(FrameworkElement image)
492 image.MouseEnter -=
new MouseEventHandler(image_MouseEnter);
493 image.MouseLeave -=
new MouseEventHandler(image_MouseLeave);
497 private void image_MouseEnter(
object sender, MouseEventArgs e)
499 Popup popup = (Popup)
FindChild(
this,
"popup");
500 if (popup !=
null && sender is UIElement)
502 popup.Placement = PlacementMode.Mouse;
503 popup.PlacementTarget = (UIElement)sender;
504 ((ItemsControl)popup.Child).ItemsSource =
BrokenRules;
509 void popup_Loaded(
object sender, RoutedEventArgs e)
511 (sender as Popup).Loaded -= popup_Loaded;
512 if (((sender as Popup).Child as UIElement).DesiredSize.Height > 0)
514 _lastPopupSize = ((sender as Popup).Child as UIElement).DesiredSize;
516 if (_lastAppSize.Width < _lastPosition.X + _popupLastPosition.X + _lastPopupSize.Width)
518 (sender as Popup).HorizontalOffset = _lastAppSize.Width - _lastPosition.X - _popupLastPosition.X - _lastPopupSize.Width;
520 if (_lastAppSize.Height < _lastPosition.Y + _popupLastPosition.Y + _lastPopupSize.Height)
522 (sender as Popup).VerticalOffset = _lastAppSize.Height - _lastPosition.Y - _popupLastPosition.Y - _lastPopupSize.Height;
526 private void image_MouseLeave(
object sender, MouseEventArgs e)
528 Popup popup = (Popup)
FindChild(
this,
"popup");
529 popup.IsOpen =
false;
532 void popup_MouseLeave(
object sender, MouseEventArgs e)
534 Popup popup = (Popup)
FindChild(
this,
"popup");
535 popup.IsOpen =
false;
540#region State management
547 if (_loading)
return;
549 Popup popup = (Popup)
FindChild(
this,
"popup");
551 popup.IsOpen =
false;
571 if (businessObject !=
null)
578 where !allRules.Contains(r)
581 var addRules = (from r in allRules
585 foreach (var rule
in removeRules)
587 foreach (var rule
in addRules)
596 select r).FirstOrDefault();
622 private string _lastState;
641 if (_loading)
return;
651 newState =
"PropertyValid";
655 if (newState != _lastState || _lastImage ==
null)
657 _lastState = newState;
658 DisablePopup(_lastImage);
659 VisualStateManager.GoToState(
this, newState, useTransitions);
660 if (newState !=
"Busy" && newState !=
"PropertyValid")
662 _lastImage = (FrameworkElement)
FindChild(
this,
string.Format(
"{0}Image", newState.ToLower()));
663 EnablePopup(_lastImage);
678 protected DependencyObject
FindChild(DependencyObject parent,
string name)
680 DependencyObject found =
null;
681 int count = VisualTreeHelper.GetChildrenCount(parent);
682 for (
int x = 0; x < count; x++)
684 DependencyObject child = VisualTreeHelper.GetChild(parent, x);
685 string childName = child.GetValue(FrameworkElement.NameProperty) as string;
686 if (childName == name)
699#region INotifyPropertyChanged Members
This is the base class from which most business objects will be derived.
This is the non-generic base class from which most business objects will be derived.
virtual bool IsPropertyBusy(Csla.Core.IPropertyInfo property)
Gets a value indicating whether a specific property is busy (has a currently executing async rule).
virtual Rules.BrokenRulesCollection BrokenRulesCollection
Provides access to the readonly collection of broken business rules for this object.
Event arguments for the BusyChanged event.
string PropertyName
Property for which the Busy value has changed.
Stores details about a specific broken business rule.
string Description
Provides access to the description of the broken rule.
RuleSeverity Severity
Gets the severity of the broken rule.
Displays a busy animation.
bool IsRunning
Gets or sets a property controlling whether the animation is running.
Displays validation information for a business object property, and manipulates an associated UI cont...
string BindingPath
Gets or sets the binding path.
override void OnApplyTemplate()
Applies the visual template.
string PropertyName
Gets or sets the name of the property.
object Property
Gets or sets the source business property to which this control is bound.
bool IsValid
Gets a value indicating whether the property is valid.
static readonly DependencyProperty PropertyProperty
Gets or sets the source business property to which this control is bound.
static readonly DependencyProperty BrokenRulesProperty
Gets the broken rules collection from the business object.
virtual void OnPropertyChanged(string propertyName)
Raises the PropertyChanged event.
ObservableCollection< BrokenRule > BrokenRules
Gets the broken rules collection from the business object.
virtual void SetSource(object dataItem)
Sets the source binding and updates status.
virtual void GoToState(bool useTransitions)
Updates the status of the Property in UI
bool IsBusy
Gets a value indicating whether the property is busy with an asynchronous operation.
PropertyStatus()
Creates an instance of the object.
DependencyObject FindChild(DependencyObject parent, string name)
Find child dependency property.
virtual void SetSource(bool propertyValueChanged)
Sets the source binding and updates status.
object Source
Gets or sets the Source.
PropertyChangedEventHandler PropertyChanged
Event raised when a property has changed.
bool IsReadOnly
Gets or sets a value indicating whether this DependencyProperty field is read only.
bool CanWrite
Gets a value indicating whether the user is authorized to write the property.
string RuleDescription
Gets the description of the most severe broken rule for this property.
object GetRealSource(object source, string bindingPath)
Gets the real source helper method.
bool CanRead
Gets a value indicating whether the user is authorized to read the property.
virtual void UpdateState()
Updates the state on control Property.
virtual void ClearState()
Clears the state.
Interface defining an object that notifies when it is busy executing an asynchronous operation.
BusyChangedEventHandler BusyChanged
Event raised when the object's busy status changes.
Defines the authorization interface through which an object can indicate which properties the current...
RuleSeverity
Values for validation rule severities.