我在资源字典中设计了一个自定义窗口。
ResourceDictionary.xaml
<ResourceDictionary>
<ControlTemplate x:Key="CustomWindowTemplate" TargetType="Window">
<Border Style="{StaticResource MainWindowBorderStyle}" Margin="20" x:Name="MainWindowBorder">
<Border.Effect>
<DropShadowEffect Color="Gray"
Direction="270"
BlurRadius="20"
ShadowDepth="3" />
</Border.Effect>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="35"/>
<RowDefinition Height="590*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Style="{StaticResource TitleBarBorderStyle}">
<Grid>
<TextBlock Style="{StaticResource TitleStyle}"/>
<Button x:Name="BtnClose" Style="{StaticResource CloseButtonStyle}"/>
</Grid>
</Border>
<Grid Grid.Row="1">
<ContentPresenter/>
</Grid>
</Grid>
</Border>
</ControlTemplate>
<Style TargetType="Window" x:Key="CustomChromeWindowStyle">
<Setter Property="Template" Value="{StaticResource CustomWindowTemplate}"/>
<Setter Property="Height" Value="600" />
<Setter Property="Width" Value="870" />
<Setter Property="ResizeMode" Value="NoResize" />
<Setter Property="AllowsTransparency" Value="True" />
<Setter Property="WindowStyle" Value="None" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Title" Value="Your Custom Window Title" />
</Style>
</ResourceDictionary>
ResourceDictionary.xaml.cs ,任何使用此ResourceDictionary的窗口都无缝地拥有这两个事件,因为它们是在ResourceDictionary.xaml上定义的
// EventSetter in CloseButtonStyle
private void BtnClose_Click(object sender, RoutedEventArgs e)
{
var closeButton = sender as Button;
var senderWindow = Window.GetWindow(closeButton);
senderWindow.Close();
}
// EventSetter in TitleBarBorderStyle
private void Border_MouseDown(object sender, MouseButtonEventArgs e)
{
var border = sender as Border;
var senderWindow = Window.GetWindow(border);
senderWindow.DragMove();
}
WindowA.xaml 示例用法
<Window x:Class="CustomWindowBase.WindowA"
Style="{DynamicResource CustomChromeWindowStyle}"
Title="Window A" Height="200" Width="300"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/CustomWindowBase.Resources;component/Dictionary/ResourceDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<!-- Window A Stuff here-->
</Grid>
</Window>
可以使用customWindow.Show()
和customWindow.ShowDialog()
打开使用此自定义shell的任何窗口。使用对话框,当用户尝试单击应用程序中的其他位置时,我将丢失闪烁或闪烁对话框窗口的事件。
无论如何通过知道打开的窗口实例是否是模态对话框而无法在ResourceDictionary.xaml中定义的Drag / Close进行无缝操作?
答案 0 :(得分:1)
这是可能的,但你必须创建一个CustomWindow
类(继承Window
)并扩展该类。
这是我的版本的一小部分。
/// <summary>
/// The custom Window in Windows10 Style.
/// </summary>
public class CustomWindow : Window
{
// ##############################################################################################################################
// Constructor
// ##############################################################################################################################
/// <summary>
/// Constructor of the <see cref="CustomWindow"/>.
/// </summary>
public CustomWindow()
{
Activated += HTWindow10_Activated;
Deactivated += HTWindow10_Deactivated;
}
static CustomWindow()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomWindow), new FrameworkPropertyMetadata(typeof(CustomWindow)));
}
// ##############################################################################################################################
// Animation and Style Events
// ##############################################################################################################################
private void HTWindow10_Deactivated(object sender, EventArgs e)
{
_WindowDropShadowEffect.Color = new System.Windows.Media.Color { A = 100, B = 26, G = 26, R = 26 }; //Dark Grey
_WindowBorder.BorderBrush = new System.Windows.Media.SolidColorBrush(new System.Windows.Media.Color { A = 255, B = 26, G = 26, R = 26 });
_WindowBorder.Background = System.Windows.Media.Brushes.White;
}
private void HTWindow10_Activated(object sender, EventArgs e)
{
_WindowDropShadowEffect.Color = new System.Windows.Media.Color { A = 100, B = 33, G = 124, R = 243 }; //Orange
_WindowBorder.BorderBrush = new System.Windows.Media.SolidColorBrush(new System.Windows.Media.Color { A = 255, B = 33, G = 124, R = 243 });
_WindowBorder.Background = System.Windows.Media.Brushes.White;
}
// ##############################################################################################################################
// EventHandler
// ##############################################################################################################################
private ComboBox _AvailableTranslation;
private Label _WindowTitle;
private Button _CloseButton;
private Rectangle _MoveRect;
private Button _MinimizeButton;
private Button _RestoreButton;
private Grid _ResizeGrid;
private MenuItem _MenuItemRestore;
private MenuItem _MenuItemMinimize;
private MenuItem _MenuItemMaximize;
private MenuItem _MenuItemClose;
private Border _WindowBorder;
private Rectangle _CloseRectangle;
private StackPanel _AvailableTranslationStackPanel;
private Image _Logo;
private DropShadowEffect _WindowDropShadowEffect;
public override void OnApplyTemplate()
{
_WindowTitle = GetTemplateChild("WindowTitle") as Label;
_CloseButton = GetTemplateChild("closeButton") as Button;
_MoveRect = GetTemplateChild("moveRectangle") as Rectangle;
_MinimizeButton = GetTemplateChild("minimizeButton") as Button;
_RestoreButton = GetTemplateChild("restoreButton") as Button;
_ResizeGrid = GetTemplateChild("resizeGrid") as Grid;
_AvailableTranslation = GetTemplateChild("availableTranslationComboBox") as ComboBox;
_AvailableTranslationStackPanel = GetTemplateChild("availableTranslationStackPanel") as StackPanel;
_MenuItemRestore = GetTemplateChild("menuItemRestore") as MenuItem;
_MenuItemMinimize = GetTemplateChild("menuItemMinimize") as MenuItem;
_MenuItemMaximize = GetTemplateChild("menuItemMaximize") as MenuItem;
_MenuItemClose = GetTemplateChild("menuItemClose") as MenuItem;
_WindowBorder = GetTemplateChild("windowBorder") as Border;
_CloseRectangle = GetTemplateChild("closeRectangle") as Rectangle;
_Logo = GetTemplateChild("logo") as Image;
_WindowDropShadowEffect = GetTemplateChild("windowDropShadowEffect") as DropShadowEffect;
base.OnApplyTemplate();
}
private HwndSource _hwndSource;
protected override void OnInitialized(EventArgs e)
{
SourceInitialized += OnSourceInitialized;
base.OnInitialized(e);
}
private void OnSourceInitialized(object sender, EventArgs e)
{
_hwndSource = (HwndSource)PresentationSource.FromVisual(this);
System.IntPtr handle = (new WinInterop.WindowInteropHelper(this)).Handle;
WinInterop.HwndSource.FromHwnd(handle).AddHook(new WinInterop.HwndSourceHook(WindowProc));
}
private void FlashTitleBar(bool active)
{
if (active)
{
_WindowDropShadowEffect.Color = new System.Windows.Media.Color { A = 100, B = 33, G = 124, R = 243 }; //Orange
_WindowBorder.BorderBrush = new System.Windows.Media.SolidColorBrush(new System.Windows.Media.Color { A = 255, B = 33, G = 124, R = 243 });
_WindowBorder.Background = System.Windows.Media.Brushes.White;
}
else
{
_WindowDropShadowEffect.Color = new System.Windows.Media.Color { A = 255, B = 0, G = 0, R = 255 }; //Red
_WindowBorder.BorderBrush = new System.Windows.Media.SolidColorBrush(new System.Windows.Media.Color { A = 255, B = 0, G = 0, R = 255 });
_WindowBorder.Background = System.Windows.Media.Brushes.Red;
}
}
private System.IntPtr WindowProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)
{
var retVal = IntPtr.Zero;
switch (msg) //http://www.mycsharp.de/wbb2/thread.php?postid=111901 Auflistung der WndProc-Message-Kommandos
{
case 0x0086: //https://msdn.microsoft.com/de-de/library/windows/desktop/ms632633%28v=vs.85%29.aspx //WM_NCACTIVATE message
retVal = DefWindowProc(hwnd, 0x0086, new IntPtr(1), new IntPtr(-1));
FlashTitleBar((int)wParam == 1 ? true : false);
handled = true;
break;
}
return retVal;
}
[DllImport("user32")]
internal static extern IntPtr DefWindowProc([In] IntPtr hwnd, [In] int msg, [In] IntPtr wParam, [In] IntPtr lParam);
}
在Gif中有点滞后。