Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ChoiceControl.cs « Xamarin.PropertyEditing.Windows - github.com/xamarin/Xamarin.PropertyEditing.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 4eb73764a5e48dc0b673136266a6f1d7deabe393 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;

namespace Xamarin.PropertyEditing.Windows
{
	internal class ChoiceItem
		: NotifyingObject
	{
		public string Name
		{
			get { return this.name; }
			set
			{
				if (this.name == value)
					return;

				this.name = value;
				OnPropertyChanged();
			}
		}

		public string Tooltip
		{
			get { return this.tooltip; }
			set
			{
				if (this.tooltip == value)
					return;

				this.tooltip = value;
				OnPropertyChanged();
			}
		}

		public object Value
		{
			get { return this.value; }
			set
			{
				if (this.value == value)
					return;

				this.value = value;
				OnPropertyChanged();
			}
		}

		private object value;
		private string tooltip;
		private string name;
	}

	[TemplatePart (Name = "list", Type = typeof(ListBox))]
	internal class ChoiceControl
		: Selector
	{
		public ChoiceControl ()
		{
			ItemContainerGenerator.StatusChanged += OnItemContainerGeneratorOnStatusChanged;
		}

		public event EventHandler SelectedItemChanged;

		protected override void OnSelectionChanged (SelectionChangedEventArgs e)
		{
			if (e.RemovedItems.Count > 0) {
				var removedToggle = GetToggle (e.RemovedItems[0]);
				if (removedToggle != null)
					removedToggle.IsChecked = false;
			}

			if (e.AddedItems.Count > 0) {
				var addedToggle = GetToggle (e.AddedItems[0]);
				if (addedToggle != null)
					addedToggle.IsChecked = true;
			}
		}

		internal void FocusSelectedItem ()
		{
			var container = ItemContainerGenerator.ContainerFromIndex (SelectedIndex) as ContentPresenter;
			if (container == null)
				throw new InvalidOperationException ("Unexpected visual tree");

			var toggle = VisualTreeHelper.GetChild (container, 0) as ToggleButton;
			if (toggle == null)
				throw new InvalidOperationException ("Children must be of ToggleButton");
			toggle.Focus ();
		}

		private ToggleButton GetToggle (object item)
		{
			var presenter = (ContentPresenter) ItemContainerGenerator.ContainerFromItem (item);
			if (presenter == null)
				return null;

			return VisualTreeHelper.GetChild (presenter, 0) as ToggleButton;
		}

		private void OnItemContainerGeneratorOnStatusChanged (object sender, EventArgs args)
		{
			if (ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated || (ItemTemplate == null && ItemTemplateSelector == null))
				return;

			// Note: this does not handle a changing items ItemsSource. It's not something that's currently required and unlikely to be.
			for (int i = 0; i < Items.Count; i++) {
				var container = ItemContainerGenerator.ContainerFromIndex (i) as ContentPresenter;
				if (container == null)
					throw new InvalidOperationException ("Unexpected visual tree");

				container.ApplyTemplate ();

				var child = VisualTreeHelper.GetChild (container, 0);
				var toggle = child as ToggleButton;
				if (toggle == null)
					throw new InvalidOperationException ("Children must be of ToggleButton. This exception may be caused by an error in the template, an uninitialized template, or a disposed template.");

				if (Equals (SelectedItem, container.DataContext))
					toggle.IsChecked = true;

				toggle.Checked += OnChoiceSelected;
			}
		}

		private void OnChoiceSelected (object sender, RoutedEventArgs e)
		{
			object selected = ((FrameworkElement) sender).DataContext;

			SetCurrentValue (SelectedItemProperty, selected);
			SelectedItemChanged?.Invoke (sender, EventArgs.Empty);
		}
	}
}