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

主要實現(xiàn)原理如下:
1、增加一塊熱點區(qū)域,鼠標進入時,觸發(fā)顯示動畫,并隱藏熱點區(qū)域
2、鼠標拖動或離開窗體,判斷窗體離屏幕邊緣的距離,符合條件的,觸發(fā)隱藏動畫,并顯示熱點區(qū)域
3、使用Window.Left屬性進行窗體動畫
需要注意的地方:
1、在拖動窗體時,不能通過窗體的Left屬性來進行判斷,因為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();
}
處理鼠標移動事件
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;
}
}
處理鼠標按下事件
private void main_MouseDown(object sender, MouseButtonEventArgs e)
{
var pos = e.GetPosition(this);
if (pos.X >= 0 && pos.Y >= 0)
isDraged = true;
}
處理鼠標離開事件
private void main_MouseLeave(object sender, MouseEventArgs e)
{
if (isDocking && isDraged == false)
{
HideWindow();
}
}
這樣就可以實現(xiàn)了一個簡單的邊緣??啃Ч,F(xiàn)在只實現(xiàn)了屏幕右側(cè)的邊緣???,左邊和上面可以如法炮制。
窗體第一次運行是不會主動隱藏的,需要手動控制 一下。
到此這篇關(guān)于基于WPF實現(xiàn)邊緣??啃Ч奈恼戮徒榻B到這了,更多相關(guān)WPF邊緣停靠內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
最新評論
最近做的某個功能需要用到邊緣停靠,WPF實現(xiàn)了下,效果如下

主要實現(xiàn)原理如下:
1、增加一塊熱點區(qū)域,鼠標進入時,觸發(fā)顯示動畫,并隱藏熱點區(qū)域
2、鼠標拖動或離開窗體,判斷窗體離屏幕邊緣的距離,符合條件的,觸發(fā)隱藏動畫,并顯示熱點區(qū)域
3、使用Window.Left屬性進行窗體動畫
需要注意的地方:
1、在拖動窗體時,不能通過窗體的Left屬性來進行判斷,因為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();
}處理鼠標移動事件
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;
}
}處理鼠標按下事件
private void main_MouseDown(object sender, MouseButtonEventArgs e)
{
var pos = e.GetPosition(this);
if (pos.X >= 0 && pos.Y >= 0)
isDraged = true;
}處理鼠標離開事件
private void main_MouseLeave(object sender, MouseEventArgs e)
{
if (isDocking && isDraged == false)
{
HideWindow();
}
}這樣就可以實現(xiàn)了一個簡單的邊緣??啃Ч,F(xiàn)在只實現(xiàn)了屏幕右側(cè)的邊緣???,左邊和上面可以如法炮制。
窗體第一次運行是不會主動隱藏的,需要手動控制 一下。
到此這篇關(guān)于基于WPF實現(xiàn)邊緣??啃Ч奈恼戮徒榻B到這了,更多相關(guān)WPF邊緣停靠內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

