diff --git a/MahApps.Metro/Controls/WindowCommands.cs b/MahApps.Metro/Controls/WindowCommands.cs index 2c27437ee0..5a7b3a8924 100644 --- a/MahApps.Metro/Controls/WindowCommands.cs +++ b/MahApps.Metro/Controls/WindowCommands.cs @@ -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; @@ -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); @@ -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 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; @@ -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() + /// + /// Gets or sets the value indicating whether to show the separator. + /// + public bool IsSeparatorVisible { - base.OnApplyTemplate(); - - separator = Template.FindName(PART_Separator, this) as UIElement; - SetSeparatorVisibility(); + get { return (bool)GetValue(IsSeparatorVisibleProperty); } + set { SetValue(IsSeparatorVisibleProperty, value); } } } } diff --git a/MahApps.Metro/Themes/WindowCommands.xaml b/MahApps.Metro/Themes/WindowCommands.xaml index a1b6e38eba..26a96cfe2d 100644 --- a/MahApps.Metro/Themes/WindowCommands.xaml +++ b/MahApps.Metro/Themes/WindowCommands.xaml @@ -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" /> + + + + + diff --git a/samples/MetroDemo/MainWindow.xaml b/samples/MetroDemo/MainWindow.xaml index d9fb7f5352..9875e8f1e3 100644 --- a/samples/MetroDemo/MainWindow.xaml +++ b/samples/MetroDemo/MainWindow.xaml @@ -205,6 +205,12 @@ + + +