Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public abstract class BaseSwitch : FrameworkElement {
- public static readonly DependencyProperty ResetElementNameBindingsProperty = DependencyProperty.Register(nameof(ResetElementNameBindings), typeof(bool),
- typeof(BaseSwitch), new FrameworkPropertyMetadata(false));
- public bool ResetElementNameBindings {
- get { return (bool)GetValue(ResetElementNameBindingsProperty); }
- set { SetValue(ResetElementNameBindingsProperty, value); }
- }
- protected abstract UIElement GetChild();
- private UIElement _child;
- private void SetActiveChild(UIElement child) {
- if (ReferenceEquals(_child, child)) return;
- /* sometimes, different errors β such as βCannot modify the logical children
- for this node at this time because a tree walk is in progress.β β happen here */
- RemoveVisualChild(_child);
- RemoveLogicalChild(_child);
- _child = child;
- AddLogicalChild(_child);
- AddVisualChild(_child);
- if (ResetElementNameBindings) {
- child.ResetElementNameBindings();
- }
- }
- protected override IEnumerator LogicalChildren => _child == null ? EmptyEnumerator.Instance :
- new SingleChildEnumerator(_child);
- protected void UpdateActiveChild() {
- SetActiveChild(GetChild());
- }
- protected static void OnChildDefiningPropertyChanged(object sender, DependencyPropertyChangedEventArgs e) {
- var b = sender as BaseSwitch;
- if (b == null) return;
- b.UpdateActiveChild();
- b.InvalidateMeasure();
- b.InvalidateVisual();
- }
- protected override Size MeasureOverride(Size constraint) {
- UpdateActiveChild();
- var e = _child;
- if (e == null) return Size.Empty;
- e.Measure(constraint);
- return e.DesiredSize;
- }
- protected override Size ArrangeOverride(Size arrangeBounds) {
- _child?.Arrange(new Rect(arrangeBounds));
- return arrangeBounds;
- }
- protected override int VisualChildrenCount => _child != null ? 1 : 0;
- protected override Visual GetVisualChild(int index) {
- var child = _child;
- if (child == null || index != 0) throw new ArgumentOutOfRangeException(nameof(index));
- return child;
- }
- protected static void OnWhenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
- var element = d as UIElement;
- if (element != null) {
- (VisualTreeHelper.GetParent(element) as BaseSwitch)?.UpdateActiveChild();
- }
- }
- }
- internal class EmptyEnumerator : IEnumerator {
- private EmptyEnumerator() { }
- public static IEnumerator Instance => _instance ?? (_instance = new EmptyEnumerator());
- public void Reset() { }
- public bool MoveNext() { return false; }
- public object Current {
- get { throw new InvalidOperationException(); }
- }
- private static IEnumerator _instance;
- }
- internal class SingleChildEnumerator : IEnumerator {
- internal SingleChildEnumerator(object child) {
- _child = child;
- _count = child == null ? 0 : 1;
- }
- object IEnumerator.Current => _index == 0 ? _child : null;
- bool IEnumerator.MoveNext() {
- return ++_index < _count;
- }
- void IEnumerator.Reset() {
- _index = -1;
- }
- private int _index = -1;
- private readonly int _count;
- private readonly object _child;
- }
- [ContentProperty(nameof(Children))]
- public abstract class ListSwitch : BaseSwitch, IAddChild, IList {
- protected readonly List<UIElement> UiElements = new List<UIElement>(2);
- public IList Children => this;
- public void CopyTo(Array array, int index) {
- ((IList)UiElements).CopyTo(array, index);
- }
- public virtual int Count => UiElements.Count;
- public object SyncRoot => ((IList)UiElements).SyncRoot;
- public bool IsSynchronized => ((IList)UiElements).IsSynchronized;
- public void RemoveAt(int index) {
- UiElements.RemoveAt(index);
- }
- public UIElement this[int index] {
- get { return UiElements[index]; }
- set {
- var vc = UiElements;
- if (!ReferenceEquals(vc[index], value)) {
- vc[index] = value;
- InvalidateMeasure();
- }
- }
- }
- public bool Contains(UIElement element) {
- return UiElements.Contains(element);
- }
- public virtual void Clear() {
- UiElements.Clear();
- }
- public int Add(UIElement element) {
- InvalidateMeasure();
- UiElements.Add(element);
- return UiElements.Count;
- }
- public int IndexOf(UIElement element) {
- return UiElements.IndexOf(element);
- }
- public void Insert(int index, UIElement element) {
- InvalidateMeasure();
- UiElements.Insert(index, element);
- }
- public void Remove(UIElement element) {
- UiElements.Remove(element);
- }
- int IList.Add(object value) {
- return Add((UIElement)value);
- }
- bool IList.Contains(object value) {
- return Contains(value as UIElement);
- }
- int IList.IndexOf(object value) {
- return IndexOf(value as UIElement);
- }
- void IList.Insert(int index, object value) {
- Insert(index, (UIElement)value);
- }
- bool IList.IsFixedSize => false;
- bool IList.IsReadOnly => false;
- void IList.Remove(object value) {
- Remove(value as UIElement);
- }
- object IList.this[int index] {
- get { return this[index]; }
- set { this[index] = (UIElement)value; }
- }
- IEnumerator IEnumerable.GetEnumerator() {
- return UiElements.GetEnumerator();
- }
- void IAddChild.AddChild(object value) {
- if (value == null) throw new ArgumentNullException(nameof(value));
- var element = value as UIElement;
- if (element == null) throw new ArgumentException("Only UIElement supported", nameof(value));
- Add(element);
- }
- void IAddChild.AddText(string text) {
- if (!string.IsNullOrWhiteSpace(text)) throw new NotSupportedException();
- }
- protected abstract bool TestChild(UIElement child);
- protected override UIElement GetChild() {
- return UiElements?.FirstOrDefault(TestChild);
- }
- }
- public class Switch : ListSwitch {
- public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(nameof(Value), typeof(object),
- typeof(Switch), new FrameworkPropertyMetadata(null, OnChildDefiningPropertyChanged));
- public object Value {
- get { return GetValue(ValueProperty); }
- set { SetValue(ValueProperty, value); }
- }
- public static object GetWhen(DependencyObject obj) {
- return obj.GetValue(WhenProperty);
- }
- public static void SetWhen(DependencyObject obj, object value) {
- obj.SetValue(WhenProperty, value);
- }
- public static readonly DependencyProperty WhenProperty = DependencyProperty.RegisterAttached("When", typeof(object),
- typeof(Switch), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsParentMeasure, OnWhenChanged));
- protected override bool TestChild(UIElement child) {
- return Value.XamlEquals(GetWhen(child));
- }
- protected override UIElement GetChild() {
- return UiElements == null ? null : (UiElements.FirstOrDefault(TestChild) ??
- UiElements.FirstOrDefault(x => x.GetValue(WhenProperty) == null));
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement