stub out things to get the beatles xbox site up and running
[moon.git] / class / System.Windows / System.Windows.Controls.Primitives / Selector.cs
blobc620a86a1595262c3cc2765fc5855dd70bc46847
1 //
2 // Selector.cs
3 //
4 // Contact:
5 // Moonlight List (moonlight-list@lists.ximian.com)
6 //
7 // Copyright 2008 Novell, Inc.
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System.Collections.Specialized;
30 using System.Windows.Input;
32 namespace System.Windows.Controls.Primitives {
33 public abstract class Selector : ItemsControl {
34 internal const string TemplateScrollViewerName = "ScrollViewer";
36 internal static readonly DependencyProperty IsSelectionActiveProperty =
37 DependencyProperty.RegisterReadOnlyCore ("IsSelectionActive", typeof(bool), typeof(Selector), null);
39 public static readonly DependencyProperty SelectedIndexProperty =
40 DependencyProperty.RegisterCore ("SelectedIndex", typeof(int), typeof(Selector),
41 new PropertyMetadata(-1, new PropertyChangedCallback(OnSelectedIndexChanged)));
43 static void OnSelectedIndexChanged (DependencyObject o, DependencyPropertyChangedEventArgs e)
45 ((Selector) o).SelectedIndexChanged (o, e);
48 // This is not a core property because it is a non-parenting property
49 public static readonly DependencyProperty SelectedItemProperty =
50 DependencyProperty.Register ("SelectedItem", typeof(object), typeof(Selector),
51 new PropertyMetadata(new PropertyChangedCallback(OnSelectedItemChanged_cb)));
54 static void OnSelectedItemChanged_cb (DependencyObject o, DependencyPropertyChangedEventArgs e)
56 ((Selector) o).SelectedItemChanged (o, e);
59 internal static void OnItemContainerStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
61 Selector s = (Selector) d;
62 Style style = (Style) e.NewValue;
64 int count = s.Items.Count;
65 for (int i = 0; i < count; i++)
67 ListBoxItem item = s.GetContainerItem (i);
68 if (item != null) // May be null if GetContainerForItemOverride has not been called yet
69 item.Style = style;
73 internal Selector ()
75 // Set default values for ScrollViewer attached properties
76 ScrollViewer.SetHorizontalScrollBarVisibility(this, ScrollBarVisibility.Auto);
77 ScrollViewer.SetVerticalScrollBarVisibility(this, ScrollBarVisibility.Auto);
80 bool Changing {
81 get; set;
84 internal bool IsSelectionActive {
85 get { return (bool) GetValue (IsSelectionActiveProperty); }
86 set { SetValueImpl (IsSelectionActiveProperty, value); }
89 [Mono.Xaml.SetPropertyDelayed]
90 public int SelectedIndex {
91 get { return (int)GetValue(SelectedIndexProperty); }
92 set { SetValue (SelectedIndexProperty, value); }
95 public object SelectedItem {
96 get { return GetValue (SelectedItemProperty); }
97 set { SetValue (SelectedItemProperty, value); }
100 internal ScrollViewer TemplateScrollViewer {
101 get; private set;
105 public event SelectionChangedEventHandler SelectionChanged;
107 void SelectedIndexChanged (DependencyObject o, DependencyPropertyChangedEventArgs e)
109 object oldItem = SelectedItem;
110 int newVal = (int) e.NewValue;
111 if (newVal == (int) e.OldValue || Changing) {
112 SelectedIndex = newVal;
113 return;
116 Changing = true;
117 try {
118 if (newVal < 0)
119 ClearValue (SelectedItemProperty);
120 else if (newVal < Items.Count)
121 SelectedItem = Items [newVal];
122 } finally {
123 Changing = false;
125 RaiseSelectionChanged (o, new SelectionChangedEventArgs (oldItem, SelectedItem));
128 void SelectedItemChanged (DependencyObject o, DependencyPropertyChangedEventArgs e)
130 if (e.NewValue == e.OldValue || Changing) {
131 SelectedItem = e.NewValue;
132 return;
135 Changing = true;
136 try {
137 int index = e.NewValue == null ? -1 : Items.IndexOf (e.NewValue);
138 if (index == -1 && e.NewValue != null) {
139 SelectedIndex = e.OldValue == null ? -1 : Items.IndexOf (e.OldValue);
140 if (e.OldValue == null)
141 ClearValue (SelectedItemProperty);
142 else
143 SelectedItem = e.OldValue;
145 else {
146 SelectedItem = e.NewValue;
147 SelectedIndex = index;
148 RaiseSelectionChanged (o, new SelectionChangedEventArgs (e.OldValue, e.NewValue));
150 } finally {
151 Changing = false;
155 void OnSelectedItemChanged (object oldValue, object newValue)
157 if (oldValue != null) {
158 ListBoxItem oldItem;
159 if (oldValue is ListBoxItem && IsItemItsOwnContainerOverride (oldValue))
160 oldItem = (ListBoxItem) oldValue;
161 else
162 oldItem = GetContainerItem (Items.IndexOf (oldValue));
164 if (oldItem != null)
165 oldItem.IsSelected = false;
168 if (newValue != null) {
169 ListBoxItem newItem;
170 if (newValue is ListBoxItem && IsItemItsOwnContainerOverride (newValue))
171 newItem = (ListBoxItem) newValue;
172 else
173 newItem = GetContainerItem (Items.IndexOf (newValue));
175 if (newItem != null) {
176 newItem.IsSelected = true;
177 newItem.Focus ();
182 void RaiseSelectionChanged (object o, SelectionChangedEventArgs e)
184 object oldVal = e.RemovedItems.Count == 1 ? e.RemovedItems [0] : null;
185 object newVal = e.AddedItems.Count == 1 ? e.AddedItems [0] : null;
186 OnSelectedItemChanged (oldVal, newVal);
188 SelectionChangedEventHandler h = SelectionChanged;
189 if (h != null)
190 h (o, e);
193 public static bool GetIsSelectionActive (DependencyObject element)
195 if (element == null)
196 throw new ArgumentNullException ("element");
198 return (bool) element.GetValue (ListBox.IsSelectionActiveProperty);
201 protected override void ClearContainerForItemOverride (DependencyObject element, object item)
203 base.ClearContainerForItemOverride (element, item);
204 ListBoxItem lbItem = (ListBoxItem) element;
205 lbItem.Content = null;
206 lbItem.IsSelected = false;
207 lbItem.ParentSelector = null;
208 if (SelectedItem == item && GetContainerItem (SelectedIndex) != null)
209 SelectedItem = null;
212 protected override void PrepareContainerForItemOverride (DependencyObject element, object item)
214 base.PrepareContainerForItemOverride (element, item);
215 ListBoxItem listBoxItem = (ListBoxItem) element;
216 listBoxItem.ParentSelector = this;
217 listBoxItem.Item = item;
218 if (listBoxItem.IsSelected && GetContainerItem (SelectedIndex) != null)
219 SelectedItem = item;
222 public override void OnApplyTemplate ()
224 base.OnApplyTemplate ();
225 TemplateScrollViewer = GetTemplateChild("ScrollViewer") as ScrollViewer;
227 if (TemplateScrollViewer != null)
229 TemplateScrollViewer.TemplatedParentHandlesScrolling = true;
230 // Update ScrollViewer values
231 TemplateScrollViewer.HorizontalScrollBarVisibility = ScrollViewer.GetHorizontalScrollBarVisibility(this);
232 TemplateScrollViewer.VerticalScrollBarVisibility = ScrollViewer.GetVerticalScrollBarVisibility(this);
236 protected override void OnItemsChanged (System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
238 switch (e.Action) {
239 case NotifyCollectionChangedAction.Add:
240 ListBoxItem item = e.NewItems [0] as ListBoxItem;
241 if (item != null && item.IsSelected) {
242 SelectedItem = item;
243 } else {
244 // Ensure we don't fire a SelectionChanged event when we're just updating the index
245 Changing = true;
246 if (e.NewStartingIndex <= SelectedIndex)
247 SelectedIndex ++;
248 Changing = false;
250 break;
251 case NotifyCollectionChangedAction.Reset:
252 SelectedIndex = -1;
253 break;
255 case NotifyCollectionChangedAction.Remove:
256 case NotifyCollectionChangedAction.Replace:
257 default:
258 // Yes this is broken, SelectedItem and SelectedIndex do get out of sync with reality.
259 break;
261 base.OnItemsChanged (e);
264 internal virtual void NotifyListItemClicked(ListBoxItem listBoxItem)
266 if (ModifierKeys.Control == (Keyboard.Modifiers & ModifierKeys.Control)) {
267 if (SelectedItem == listBoxItem.Item)
268 SelectedItem = null;
269 } else {
270 SelectedItem = listBoxItem.Item;
274 internal virtual void NotifyListItemLoaded (ListBoxItem listBoxItem)
276 if (listBoxItem.Item == SelectedItem) {
277 listBoxItem.IsSelected = true;
278 listBoxItem.Focus ();
282 internal virtual void NotifyListItemGotFocus(ListBoxItem listBoxItemNewFocus)
287 internal virtual void NotifyListItemLostFocus(ListBoxItem listBoxItemOldFocus)