基于WPF實現(xiàn)邊緣??啃Ч?/h1>
更新時間:2024年01月09日 09:30:04 作者:zhaotianff
這篇文章主要為大家信息介紹了如何基于WPF實現(xiàn)邊緣??啃Ч?文中的示例代碼講解詳細(xì),具有一定的借鑒價值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
最近做的某個功能需要用到邊緣??浚琖PF實現(xiàn)了下,效果如下

主要實現(xiàn)原理如下:
1、增加一塊熱點區(qū)域,鼠標(biāo)進(jìn)入時,觸發(fā)顯示動畫,并隱藏?zé)狳c區(qū)域
2、鼠標(biāo)拖動或離開窗體,判斷窗體離屏幕邊緣的距離,符合條件的,觸發(fā)隱藏動畫,并顯示熱點區(qū)域
3、使用Window.Left屬性進(jìn)行窗體動畫
需要注意的地方:
1、在拖動窗體時,不能通過窗體的Left屬性來進(jìn)行判斷,因為Left沒有刷新,可以通過Win32 API 函數(shù)GetWindowRect來獲取
2、可以增加緩動動畫,使動畫效果更好。
實現(xiàn)代碼如下:
MainWindow.xaml
在XAML里定義了顯示和隱藏的動畫,窗體定義了兩列,第一列就是隱藏時用于顯示窗體的熱點區(qū)域
<blur:BlurWindow x:Class="WpfDockDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfDockDemo"
xmlns:blur="clr-namespace:TianXiaTech;assembly=BlurWindow"
mc:Ignorable="d"
Title="MainWindow" Height="650" Width="305" TitleVisibility="Collapsed" IconVisibility="Collapsed" ControlBoxVisibility="Collapsed"
Background="White" Name="main" MouseMove="BlurWindow_MouseMove" MouseLeave="main_MouseLeave" Topmost="True" PreviewMouseDown="main_MouseDown">
<blur:BlurWindow.Resources>
<Storyboard x:Key="hiddenAnimation">
<DoubleAnimation Storyboard.TargetName="main" Storyboard.TargetProperty="(Window.Left)" Duration="0:0:0.5" AutoReverse="False">
<DoubleAnimation.EasingFunction>
<BackEase Amplitude="0.3"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
<Storyboard x:Key="showAnimation">
<DoubleAnimation Storyboard.TargetName="main" Storyboard.TargetProperty="(Window.Left)" Duration="0:0:0.5" AutoReverse="False">
<DoubleAnimation.EasingFunction>
<BackEase Amplitude="0.3" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</blur:BlurWindow.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid Background="Transparent" MouseEnter="grid_DockArea_MouseEnter" Name="grid_DockArea" Visibility="Collapsed">
<Border Height="{Binding ElementName=main,Path=ActualHeight}" VerticalAlignment="Center" Width="2" Background="Silver">
<Border.Effect>
<DropShadowEffect Color="Black" Opacity=".3"></DropShadowEffect>
</Border.Effect>
</Border>
</Grid>
<!--網(wǎng)上隨便找的圖-->
<Image Margin="10" Source="https://pic1.zhimg.com/80/v2-46ae37aad7cb70b4dc4ad4489cdaffdd_720w.webp?source=2c26e567" Grid.Column="1" PreviewMouseDown="main_MouseDown" >
<Image.Effect>
<DropShadowEffect Opacity=".5"></DropShadowEffect>
</Image.Effect>
</Image>
</Grid>
</blur:BlurWindow>
引入用到的api函數(shù)
public struct POINT
{
public int x;
public int y;
}
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
public class User32
{
[DllImport("User32.dll")]
public static extern int GetCursorPos(ref POINT point);
[DllImport("User32.dll")]
public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
}
定義一些用于記錄窗體狀態(tài)的變量
private bool isDocking = true; //是否啟用邊緣???
private bool isAnimation = false; //是否正在動畫中
private bool isDraged = false; //是否正在拖動中
定義用于窗體顯示和隱藏動畫的函數(shù)
private void HideWindow(double left = -1)
{
if (left == -1)
{
RECT rect = new RECT();
User32.GetWindowRect(new WindowInteropHelper(this).Handle, ref rect);
left = rect.left;
}
if (SystemParameters.PrimaryScreenWidth - left - this.Width > 15)
return;
if (isAnimation)
return;
isAnimation = true;
hiddenAnimation.Begin();
}
private void ShowWindow()
{
if (isAnimation)
return;
grid_DockArea.Visibility = Visibility.Collapsed;
isAnimation = true;
showAnimation.Begin();
}
處理鼠標(biāo)移動事件
private void BlurWindow_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
try
{
this.DragMove();
isDraged = true;
}
catch
{
}
}
if (e.LeftButton == MouseButtonState.Released && isDocking == true && isDraged == true)
{
POINT point = new POINT();
if (User32.GetCursorPos(ref point) == 1)
{
var pos = e.GetPosition(this);
if (pos.X < 0 && pos.Y < 0)
HideWindow();
}
isDraged = false;
}
}
處理鼠標(biāo)按下事件
private void main_MouseDown(object sender, MouseButtonEventArgs e)
{
var pos = e.GetPosition(this);
if (pos.X >= 0 && pos.Y >= 0)
isDraged = true;
}
處理鼠標(biāo)離開事件
private void main_MouseLeave(object sender, MouseEventArgs e)
{
if (isDocking && isDraged == false)
{
HideWindow();
}
}
這樣就可以實現(xiàn)了一個簡單的邊緣??啃Ч,F(xiàn)在只實現(xiàn)了屏幕右側(cè)的邊緣??浚筮吅蜕厦婵梢匀绶ㄅ谥?。
窗體第一次運(yùn)行是不會主動隱藏的,需要手動控制 一下。
到此這篇關(guān)于基于WPF實現(xiàn)邊緣停靠效果的文章就介紹到這了,更多相關(guān)WPF邊緣??績?nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
最新評論
最近做的某個功能需要用到邊緣??浚琖PF實現(xiàn)了下,效果如下
主要實現(xiàn)原理如下:
1、增加一塊熱點區(qū)域,鼠標(biāo)進(jìn)入時,觸發(fā)顯示動畫,并隱藏?zé)狳c區(qū)域
2、鼠標(biāo)拖動或離開窗體,判斷窗體離屏幕邊緣的距離,符合條件的,觸發(fā)隱藏動畫,并顯示熱點區(qū)域
3、使用Window.Left屬性進(jìn)行窗體動畫
需要注意的地方:
1、在拖動窗體時,不能通過窗體的Left屬性來進(jìn)行判斷,因為Left沒有刷新,可以通過Win32 API 函數(shù)GetWindowRect來獲取
2、可以增加緩動動畫,使動畫效果更好。
實現(xiàn)代碼如下:
MainWindow.xaml
在XAML里定義了顯示和隱藏的動畫,窗體定義了兩列,第一列就是隱藏時用于顯示窗體的熱點區(qū)域
<blur:BlurWindow x:Class="WpfDockDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfDockDemo" xmlns:blur="clr-namespace:TianXiaTech;assembly=BlurWindow" mc:Ignorable="d" Title="MainWindow" Height="650" Width="305" TitleVisibility="Collapsed" IconVisibility="Collapsed" ControlBoxVisibility="Collapsed" Background="White" Name="main" MouseMove="BlurWindow_MouseMove" MouseLeave="main_MouseLeave" Topmost="True" PreviewMouseDown="main_MouseDown"> <blur:BlurWindow.Resources> <Storyboard x:Key="hiddenAnimation"> <DoubleAnimation Storyboard.TargetName="main" Storyboard.TargetProperty="(Window.Left)" Duration="0:0:0.5" AutoReverse="False"> <DoubleAnimation.EasingFunction> <BackEase Amplitude="0.3"/> </DoubleAnimation.EasingFunction> </DoubleAnimation> </Storyboard> <Storyboard x:Key="showAnimation"> <DoubleAnimation Storyboard.TargetName="main" Storyboard.TargetProperty="(Window.Left)" Duration="0:0:0.5" AutoReverse="False"> <DoubleAnimation.EasingFunction> <BackEase Amplitude="0.3" /> </DoubleAnimation.EasingFunction> </DoubleAnimation> </Storyboard> </blur:BlurWindow.Resources> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="5"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid Background="Transparent" MouseEnter="grid_DockArea_MouseEnter" Name="grid_DockArea" Visibility="Collapsed"> <Border Height="{Binding ElementName=main,Path=ActualHeight}" VerticalAlignment="Center" Width="2" Background="Silver"> <Border.Effect> <DropShadowEffect Color="Black" Opacity=".3"></DropShadowEffect> </Border.Effect> </Border> </Grid> <!--網(wǎng)上隨便找的圖--> <Image Margin="10" Source="https://pic1.zhimg.com/80/v2-46ae37aad7cb70b4dc4ad4489cdaffdd_720w.webp?source=2c26e567" Grid.Column="1" PreviewMouseDown="main_MouseDown" > <Image.Effect> <DropShadowEffect Opacity=".5"></DropShadowEffect> </Image.Effect> </Image> </Grid> </blur:BlurWindow>
引入用到的api函數(shù)
public struct POINT { public int x; public int y; } public struct RECT { public int left; public int top; public int right; public int bottom; } public class User32 { [DllImport("User32.dll")] public static extern int GetCursorPos(ref POINT point); [DllImport("User32.dll")] public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect); }
定義一些用于記錄窗體狀態(tài)的變量
private bool isDocking = true; //是否啟用邊緣??? private bool isAnimation = false; //是否正在動畫中 private bool isDraged = false; //是否正在拖動中
定義用于窗體顯示和隱藏動畫的函數(shù)
private void HideWindow(double left = -1) { if (left == -1) { RECT rect = new RECT(); User32.GetWindowRect(new WindowInteropHelper(this).Handle, ref rect); left = rect.left; } if (SystemParameters.PrimaryScreenWidth - left - this.Width > 15) return; if (isAnimation) return; isAnimation = true; hiddenAnimation.Begin(); } private void ShowWindow() { if (isAnimation) return; grid_DockArea.Visibility = Visibility.Collapsed; isAnimation = true; showAnimation.Begin(); }
處理鼠標(biāo)移動事件
private void BlurWindow_MouseMove(object sender, MouseEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed) { try { this.DragMove(); isDraged = true; } catch { } } if (e.LeftButton == MouseButtonState.Released && isDocking == true && isDraged == true) { POINT point = new POINT(); if (User32.GetCursorPos(ref point) == 1) { var pos = e.GetPosition(this); if (pos.X < 0 && pos.Y < 0) HideWindow(); } isDraged = false; } }
處理鼠標(biāo)按下事件
private void main_MouseDown(object sender, MouseButtonEventArgs e) { var pos = e.GetPosition(this); if (pos.X >= 0 && pos.Y >= 0) isDraged = true; }
處理鼠標(biāo)離開事件
private void main_MouseLeave(object sender, MouseEventArgs e) { if (isDocking && isDraged == false) { HideWindow(); } }
這樣就可以實現(xiàn)了一個簡單的邊緣??啃Ч,F(xiàn)在只實現(xiàn)了屏幕右側(cè)的邊緣??浚筮吅蜕厦婵梢匀绶ㄅ谥?。
窗體第一次運(yùn)行是不會主動隱藏的,需要手動控制 一下。
到此這篇關(guān)于基于WPF實現(xiàn)邊緣停靠效果的文章就介紹到這了,更多相關(guān)WPF邊緣??績?nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!