Skip to content

Commit

Permalink
Merge pull request #2175 from MahApps/WindowCommandsItem-Visibility
Browse files Browse the repository at this point in the history
Fix WindowCommandsItem visibility
  • Loading branch information
punker76 committed Oct 23, 2015
2 parents 2468043 + d2d7364 commit 47f1b4b
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 38 deletions.
126 changes: 88 additions & 38 deletions MahApps.Metro/Controls/WindowCommands.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
using System.Collections.Specialized;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

Expand Down Expand Up @@ -157,13 +161,60 @@ protected override bool IsItemItsOwnContainerOverride(object item)
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
base.PrepareContainerForItemOverride(element, item);

this.AttachVisibilityHandler(element as WindowCommandsItem, item as UIElement);
if ((Items.Count > 0) && (ReferenceEquals(item, Items[Items.Count - 1])))
{
ResetSeparators(false);
}
}

protected override void ClearContainerForItemOverride(DependencyObject element, object item)
{
base.ClearContainerForItemOverride(element, item);
this.DetachVisibilityHandler(element as WindowCommandsItem);
ResetSeparators(false);
}

private void AttachVisibilityHandler(WindowCommandsItem container, UIElement item)
{
if (container != null)
{
// hide the container, if there is no UIElement
if (null == item)
{
container.Visibility = Visibility.Collapsed;
return;
}

container.Visibility = item.Visibility;
var isVisibilityNotifier = new PropertyChangeNotifier(item, UIElement.VisibilityProperty);
isVisibilityNotifier.ValueChanged += VisibilityPropertyChanged;
container.VisibilityPropertyChangeNotifier = isVisibilityNotifier;
}
}

private void DetachVisibilityHandler(WindowCommandsItem container)
{
if (container != null)
{
container.VisibilityPropertyChangeNotifier = null;
}
}

private void VisibilityPropertyChanged(object sender, EventArgs e)
{
var item = sender as UIElement;
if (item != null)
{
var container = GetWindowCommandsItem(item);
if (container != null)
{
container.Visibility = item.Visibility;
ResetSeparators();
}
}
}

protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(e);
Expand All @@ -172,25 +223,43 @@ protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)

private void ResetSeparators(bool reset = true)
{
if (Items.Count == 0)
{
return;
}

var windowCommandsItems = this.GetWindowCommandsItems().ToList();

if (reset)
{
for (var i = 0; i < Items.Count - 1; i++)
foreach (var windowCommandsItem in windowCommandsItems)
{
var container = ItemContainerGenerator.ContainerFromIndex(i) as WindowCommandsItem;
if (container != null)
{
container.IsSeparatorVisible = ShowSeparators;
}
windowCommandsItem.IsSeparatorVisible = ShowSeparators;
}
}

var lastContainer = ItemContainerGenerator.ContainerFromIndex(Items.Count - 1) as WindowCommandsItem;
var lastContainer = windowCommandsItems.LastOrDefault(i => i.IsVisible);
if (lastContainer != null)
{
lastContainer.IsSeparatorVisible = ShowSeparators && ShowLastSeparator;
}
}

private WindowCommandsItem GetWindowCommandsItem(object item)
{
var windowCommandsItem = item as WindowCommandsItem;
if (windowCommandsItem != null)
{
return windowCommandsItem;
}
return (WindowCommandsItem)this.ItemContainerGenerator.ContainerFromItem(item);
}

private IEnumerable<WindowCommandsItem> GetWindowCommandsItems()
{
return (from object item in (IEnumerable)this.Items select this.GetWindowCommandsItem(item)).Where(i => i != null);
}

private void WindowCommands_Loaded(object sender, RoutedEventArgs e)
{
this.Loaded -= WindowCommands_Loaded;
Expand Down Expand Up @@ -233,38 +302,19 @@ public class WindowCommandsItem : ContentControl
private const string PART_ContentPresenter = "PART_ContentPresenter";
private const string PART_Separator = "PART_Separator";

private UIElement separator;
private bool isSeparatorVisible = true;

public bool IsSeparatorVisible
{
get { return isSeparatorVisible; }
set
{
if (isSeparatorVisible == value)
{
return;
}

isSeparatorVisible = value;
SetSeparatorVisibility();
}
}
internal PropertyChangeNotifier VisibilityPropertyChangeNotifier { get; set; }

private void SetSeparatorVisibility()
{
if (separator != null)
{
separator.Visibility = IsSeparatorVisible ? Visibility.Visible : Visibility.Hidden;
}
}
public static readonly DependencyProperty IsSeparatorVisibleProperty =
DependencyProperty.Register("IsSeparatorVisible", typeof(bool), typeof(WindowCommandsItem),
new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits|FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender));

public override void OnApplyTemplate()
/// <summary>
/// Gets or sets the value indicating whether to show the separator.
/// </summary>
public bool IsSeparatorVisible
{
base.OnApplyTemplate();

separator = Template.FindName(PART_Separator, this) as UIElement;
SetSeparatorVisibility();
get { return (bool)GetValue(IsSeparatorVisibleProperty); }
set { SetValue(IsSeparatorVisibleProperty, value); }
}
}
}
9 changes: 9 additions & 0 deletions MahApps.Metro/Themes/WindowCommands.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,17 @@
Fill="{Binding Foreground, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type Controls:WindowCommands}}}"
IsHitTestVisible="False"
SnapsToDevicePixels="True"
UseLayoutRounding="True"
Opacity="0.25" />
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsSeparatorVisible"
Value="False">
<Setter TargetName="PART_Separator"
Property="Visibility"
Value="Collapsed" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
Expand Down
6 changes: 6 additions & 0 deletions samples/MetroDemo/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@
<MenuItem Header="Window with a Border" Click="MenuWindowWithBorderOnClick" />
<MenuItem Header="Window with a Glow" Click="MenuWindowWithGlowOnClick" />
<MenuItem Header="Window with drop shadow" Click="MenuWindowWithShadowOnClick" />
<Separator />
<MenuItem IsCheckable="True" Header="ShowSeparators (RightWindowCommands)" x:Name="ShowSeparatorsMI"
IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Controls:MetroWindow}}, Path=RightWindowCommands.ShowSeparators}" />
<MenuItem IsCheckable="True" Header="ShowLastSeparator in (RightWindowCommands)"
IsEnabled="{Binding ElementName=ShowSeparatorsMI, Path=IsChecked, Mode=OneWay}"
IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Controls:MetroWindow}}, Path=RightWindowCommands.ShowLastSeparator}" />
</MenuItem>
</Menu>

Expand Down

0 comments on commit 47f1b4b

Please sign in to comment.