Skip to content

Commit d2d7364

Browse files
committed
fix visibility of WindowCommandsItem
- only show WindowCommandsItem with UIElements - handle visibility of WindowCommandsItem content
1 parent 8e0ad19 commit d2d7364

File tree

2 files changed

+97
-38
lines changed

2 files changed

+97
-38
lines changed

MahApps.Metro/Controls/WindowCommands.cs

Lines changed: 88 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
using System.Collections.Specialized;
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Collections.Specialized;
25
using System.ComponentModel;
6+
using System.Linq;
37
using System.Windows;
48
using System.Windows.Controls;
59

@@ -157,13 +161,60 @@ protected override bool IsItemItsOwnContainerOverride(object item)
157161
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
158162
{
159163
base.PrepareContainerForItemOverride(element, item);
160-
164+
this.AttachVisibilityHandler(element as WindowCommandsItem, item as UIElement);
161165
if ((Items.Count > 0) && (ReferenceEquals(item, Items[Items.Count - 1])))
162166
{
163167
ResetSeparators(false);
164168
}
165169
}
166170

171+
protected override void ClearContainerForItemOverride(DependencyObject element, object item)
172+
{
173+
base.ClearContainerForItemOverride(element, item);
174+
this.DetachVisibilityHandler(element as WindowCommandsItem);
175+
ResetSeparators(false);
176+
}
177+
178+
private void AttachVisibilityHandler(WindowCommandsItem container, UIElement item)
179+
{
180+
if (container != null)
181+
{
182+
// hide the container, if there is no UIElement
183+
if (null == item)
184+
{
185+
container.Visibility = Visibility.Collapsed;
186+
return;
187+
}
188+
189+
container.Visibility = item.Visibility;
190+
var isVisibilityNotifier = new PropertyChangeNotifier(item, UIElement.VisibilityProperty);
191+
isVisibilityNotifier.ValueChanged += VisibilityPropertyChanged;
192+
container.VisibilityPropertyChangeNotifier = isVisibilityNotifier;
193+
}
194+
}
195+
196+
private void DetachVisibilityHandler(WindowCommandsItem container)
197+
{
198+
if (container != null)
199+
{
200+
container.VisibilityPropertyChangeNotifier = null;
201+
}
202+
}
203+
204+
private void VisibilityPropertyChanged(object sender, EventArgs e)
205+
{
206+
var item = sender as UIElement;
207+
if (item != null)
208+
{
209+
var container = GetWindowCommandsItem(item);
210+
if (container != null)
211+
{
212+
container.Visibility = item.Visibility;
213+
ResetSeparators();
214+
}
215+
}
216+
}
217+
167218
protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
168219
{
169220
base.OnItemsChanged(e);
@@ -172,25 +223,43 @@ protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
172223

173224
private void ResetSeparators(bool reset = true)
174225
{
226+
if (Items.Count == 0)
227+
{
228+
return;
229+
}
230+
231+
var windowCommandsItems = this.GetWindowCommandsItems().ToList();
232+
175233
if (reset)
176234
{
177-
for (var i = 0; i < Items.Count - 1; i++)
235+
foreach (var windowCommandsItem in windowCommandsItems)
178236
{
179-
var container = ItemContainerGenerator.ContainerFromIndex(i) as WindowCommandsItem;
180-
if (container != null)
181-
{
182-
container.IsSeparatorVisible = ShowSeparators;
183-
}
237+
windowCommandsItem.IsSeparatorVisible = ShowSeparators;
184238
}
185239
}
186240

187-
var lastContainer = ItemContainerGenerator.ContainerFromIndex(Items.Count - 1) as WindowCommandsItem;
241+
var lastContainer = windowCommandsItems.LastOrDefault(i => i.IsVisible);
188242
if (lastContainer != null)
189243
{
190244
lastContainer.IsSeparatorVisible = ShowSeparators && ShowLastSeparator;
191245
}
192246
}
193247

248+
private WindowCommandsItem GetWindowCommandsItem(object item)
249+
{
250+
var windowCommandsItem = item as WindowCommandsItem;
251+
if (windowCommandsItem != null)
252+
{
253+
return windowCommandsItem;
254+
}
255+
return (WindowCommandsItem)this.ItemContainerGenerator.ContainerFromItem(item);
256+
}
257+
258+
private IEnumerable<WindowCommandsItem> GetWindowCommandsItems()
259+
{
260+
return (from object item in (IEnumerable)this.Items select this.GetWindowCommandsItem(item)).Where(i => i != null);
261+
}
262+
194263
private void WindowCommands_Loaded(object sender, RoutedEventArgs e)
195264
{
196265
this.Loaded -= WindowCommands_Loaded;
@@ -233,38 +302,19 @@ public class WindowCommandsItem : ContentControl
233302
private const string PART_ContentPresenter = "PART_ContentPresenter";
234303
private const string PART_Separator = "PART_Separator";
235304

236-
private UIElement separator;
237-
private bool isSeparatorVisible = true;
238-
239-
public bool IsSeparatorVisible
240-
{
241-
get { return isSeparatorVisible; }
242-
set
243-
{
244-
if (isSeparatorVisible == value)
245-
{
246-
return;
247-
}
248-
249-
isSeparatorVisible = value;
250-
SetSeparatorVisibility();
251-
}
252-
}
305+
internal PropertyChangeNotifier VisibilityPropertyChangeNotifier { get; set; }
253306

254-
private void SetSeparatorVisibility()
255-
{
256-
if (separator != null)
257-
{
258-
separator.Visibility = IsSeparatorVisible ? Visibility.Visible : Visibility.Hidden;
259-
}
260-
}
307+
public static readonly DependencyProperty IsSeparatorVisibleProperty =
308+
DependencyProperty.Register("IsSeparatorVisible", typeof(bool), typeof(WindowCommandsItem),
309+
new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits|FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender));
261310

262-
public override void OnApplyTemplate()
311+
/// <summary>
312+
/// Gets or sets the value indicating whether to show the separator.
313+
/// </summary>
314+
public bool IsSeparatorVisible
263315
{
264-
base.OnApplyTemplate();
265-
266-
separator = Template.FindName(PART_Separator, this) as UIElement;
267-
SetSeparatorVisibility();
316+
get { return (bool)GetValue(IsSeparatorVisibleProperty); }
317+
set { SetValue(IsSeparatorVisibleProperty, value); }
268318
}
269319
}
270320
}

MahApps.Metro/Themes/WindowCommands.xaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,17 @@
211211
Fill="{Binding Foreground, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type Controls:WindowCommands}}}"
212212
IsHitTestVisible="False"
213213
SnapsToDevicePixels="True"
214+
UseLayoutRounding="True"
214215
Opacity="0.25" />
215216
</StackPanel>
217+
<ControlTemplate.Triggers>
218+
<Trigger Property="IsSeparatorVisible"
219+
Value="False">
220+
<Setter TargetName="PART_Separator"
221+
Property="Visibility"
222+
Value="Collapsed" />
223+
</Trigger>
224+
</ControlTemplate.Triggers>
216225
</ControlTemplate>
217226
</Setter.Value>
218227
</Setter>

0 commit comments

Comments
 (0)