欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#?wpf實(shí)現(xiàn)任意控件更多調(diào)整大小功能

 更新時(shí)間:2024年01月23日 09:31:40   作者:CodeOfCC  
這篇文章主要為大家詳細(xì)介紹了C#?wpf實(shí)現(xiàn)任意控件更多調(diào)整大小功能的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

前言

上一章我們已經(jīng)實(shí)現(xiàn)了任意控件統(tǒng)一的拖動(dòng)調(diào)整功能,能夠方便的給任意控件設(shè)置拖動(dòng)調(diào)整大小。開(kāi)發(fā)過(guò)程中發(fā)現(xiàn)還是有些功能可以繼續(xù)拓展的,比如cs代碼觸發(fā)拖動(dòng)、自定義模板、交叉拖動(dòng)、限制拖動(dòng)范圍等功能。有功能實(shí)現(xiàn)起來(lái)不算太容易,卻很有實(shí)用價(jià)值。

一、添加的功能

第四章基礎(chǔ)上添加了如下功能。

1、任意控件DragResize

我們知道wpf的Window有DragMove功能,在鼠標(biāo)左鍵按下事件中調(diào)用此方法就能實(shí)現(xiàn)拖動(dòng)功能很方便。對(duì)于調(diào)整大小也可以實(shí)現(xiàn)類(lèi)似的DragResize功能, 實(shí)際效果和點(diǎn)擊畫(huà)板拖出一個(gè)形狀差不多。

代碼示例如下:

 /// <summary>
 /// 手動(dòng)觸發(fā)拖動(dòng)改變大小,與Window.DragMove類(lèi)似,只能在鼠標(biāo)左鍵按下時(shí)調(diào)用。
 /// 實(shí)際效果和點(diǎn)擊畫(huà)板拖出一個(gè)形狀差不多。
 /// 此方法為拓展方法,F(xiàn)rameworkElement的子類(lèi)控件(即有寬高屬性的控件)都可以調(diào)用此方法。
 /// </summary>
 /// <param name="elememt"></param>
 /// <returns>返回Task,await等待拖動(dòng)完成</returns>
 /// <exception cref="InvalidOperationException"></exception>
 public static async Task DragResize(this FrameworkElement elememt)
 {
     if (Mouse.LeftButton != MouseButtonState.Pressed)
     {
         throw new InvalidOperationException("Left button down to call this method");
     }
     if (elememt.Parent == null && elememt is not Window)
     {
         throw new InvalidOperationException("Element should be on the visual tree");
     }
     //生成Resizeable對(duì)象,第四章完整代碼中。
     //獲取右下角Thumb
     //手動(dòng)觸發(fā)Thumb拖動(dòng)事件
     //等待拖動(dòng)完成
 }

2、邊界限制

添加一個(gè)IsResizeInBounds附加屬性,表示拖動(dòng)范圍是否在父控件內(nèi)。

代碼示例如下:

public static bool GetIsResizeInBounds(DependencyObject obj)
{
    return (bool)obj.GetValue(IsResizeInBoundsProperty);
}

public static void SetIsResizeInBounds(DependencyObject obj, bool value)
{
    obj.SetValue(IsResizeInBoundsProperty, value);
}

/// <summary>
/// 是否在父控件范圍內(nèi)拖動(dòng)
/// </summary>
public static readonly DependencyProperty IsResizeInBoundsProperty =
    DependencyProperty.RegisterAttached("IsResizeInBounds", typeof(bool), typeof(Resize), new PropertyMetadata(false));

第四章的拖動(dòng)邏輯中添加相應(yīng)的限制功能,本質(zhì)上就是判斷如果超出邊界則控件剛好依附在邊界上,代碼如下:

 var dx = left - margin.Left;
 var dy = top - margin.Top;
 if (GetIsResizeInBounds(c))
 {
     var pos = c.GetPosition();
     var parent = _resizeTarget.Parent as FrameworkElement;
     Size size;
     if (parent == null)
     {
         size.Width = SystemParameters.PrimaryScreenWidth;
         size.Height = SystemParameters.PrimaryScreenHeight;
     }
     else
     {
         size.Width = parent.ActualWidth;
         size.Height = parent.ActualHeight;
     }

???????     if (pos.X + dx < 0)
     {
         left = -pos.X + margin.Left;
         width = pos.X + c.ActualWidth;
     }
     else if (pos.X + dx + width > size.Width)
     {
         width = size.Width - pos.X;
         right = margin.Right + c.ActualWidth - width;
     }
     if (pos.Y + dy < 0)
     {
         top = -pos.Y + margin.Top;
         height = pos.Y + c.ActualHeight;
     }
     else if (pos.Y + dy + height > size.Height)
     {
         height = size.Height - pos.Y;
         bottom = margin.Bottom + c.ActualHeight - height;
     }
 }                

3、交叉拖動(dòng)

交叉拖動(dòng)是曾經(jīng)用gdi畫(huà)圖時(shí)會(huì)出現(xiàn)的一種情況,gdi繪制的寬高可以為負(fù)數(shù),所以可以直接穿過(guò)起點(diǎn)反向拖動(dòng)也能繪制出圖形。在wpf中的控件是不支持寬高負(fù)數(shù)的,所以我們需要用其他方式實(shí)現(xiàn)。

下列步驟以橫向?yàn)槔?/p>

(1)判斷控件邊界

 if (width < 0)

(2)固定到控件邊界

SetTargetMargin為前3章的集合,根據(jù)不同控件類(lèi)型比如Window是設(shè)置Left、Top、Grid則設(shè)置Margin等。minWidth是控件的MinWidth屬性。margin參考第四張完整代碼。

if (thumb.HorizontalAlignment == HorizontalAlignment.Left)
//左拖動(dòng)點(diǎn)
{
    SetTargetMargin(new Thickness(margin.Left + c.Width - minWidth, margin.Top, margin.Right - c.Width + minWidth, margin.Bottom));
}
else
//右拖動(dòng)點(diǎn)
{
    SetTargetMargin(new Thickness(margin.Left - c.Width + minWidth, margin.Top, margin.Right + c.Width - minWidth, margin.Bottom));
}

(3)事件轉(zhuǎn)移

//當(dāng)前拖動(dòng)點(diǎn)觸發(fā)鼠標(biāo)彈起事件
MouseButtonEventArgs upEvent = new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, MouseButton.Left)
{ RoutedEvent = UIElement.MouseLeftButtonUpEvent };
thumb.RaiseEvent(upEvent);
//反向拖動(dòng)點(diǎn)觸發(fā)鼠標(biāo)按下事件
MouseButtonEventArgs downEvent = new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, MouseButton.Left)
{ RoutedEvent = UIElement.MouseLeftButtonDownEvent };
t.RaiseEvent(downEvent);

4、拖動(dòng)點(diǎn)模板

添加附加屬性ThumbsTemplate

public static ControlTemplate GetThumbsTemplate(DependencyObject obj)
{
    return (ControlTemplate)obj.GetValue(ThumbsTemplateProperty);
}

public static void SetThumbsTemplate(DependencyObject obj, ControlTemplate value)
{
    obj.SetValue(ThumbsTemplateProperty, value);
}

/// <summary>
/// 拖動(dòng)點(diǎn)的模板
/// </summary>
public static readonly DependencyProperty ThumbsTemplateProperty =
    DependencyProperty.RegisterAttached("ThumbsTemplate", typeof(ControlTemplate), typeof(Resize), new PropertyMetadata(null));

生成拖動(dòng)點(diǎn)時(shí)會(huì)應(yīng)用模板

var thumbsTemplate = GetThumbsTemplate(_resizeTarget);
thumb.Template = thumbsTemplate;

5、拖動(dòng)點(diǎn)容器模板

拖動(dòng)點(diǎn)的容器模板,主要用于設(shè)置margin調(diào)整拖動(dòng)點(diǎn)的整體位置,添加附加屬性ThumbsPanel。

 public static ItemsPanelTemplate GetThumbsPanel(DependencyObject obj)
 {
     return (ItemsPanelTemplate)obj.GetValue(ThumbsPanelProperty);
 }

 public static void SetThumbsPanel(DependencyObject obj, ItemsPanelTemplate value)
 {
     obj.SetValue(ThumbsPanelProperty, value);
 }

 /// <summary>
 /// 拖動(dòng)點(diǎn)的容器,主要用于設(shè)置margin
 /// </summary>
 public static readonly DependencyProperty ThumbsPanelProperty =
     DependencyProperty.RegisterAttached("ThumbsPanel", typeof(ItemsPanelTemplate), typeof(Resize), new PropertyMetadata(null));

生成拖動(dòng)點(diǎn)布局時(shí)會(huì)應(yīng)用模板

var itemsPanel = GetThumbsPanel(_resizeTarget);
_defalutPanel.ItemsPanel = itemsPanel;

6、整體模板

拖動(dòng)點(diǎn)模板和拖動(dòng)點(diǎn)布局模板已經(jīng)很大程度靈活了使用,如果需要更高的定制性,直接使用整體模板,整體模板賦值后拖動(dòng)點(diǎn)模板和拖動(dòng)點(diǎn)布局模板會(huì)失效。此功能與第四章的ResizeTemplate相同但名稱(chēng)改為T(mén)emplate。基本規(guī)則是第一級(jí)控件為容器、第二級(jí)控件為T(mén)humb類(lèi)型自動(dòng)識(shí)別為拖動(dòng)點(diǎn),拖動(dòng)方向由HorizontalAlignment和VerticalAlignment決定。

7、窗口平滑拖動(dòng)

之所有要對(duì)窗口拖動(dòng)平滑處理是因?yàn)?,自定義的調(diào)整大小只能設(shè)置Window的Left、Top、Width、Height,當(dāng)窗口進(jìn)行左或上拖動(dòng)時(shí)右或下會(huì)出現(xiàn)殘影,這種情況通過(guò)SetWindowPos和MoveWindow也無(wú)法改善。在不使用窗口自帶的拖動(dòng)功能的情況下,目前筆者研究出的方法就是使用透明窗口全屏,控件模擬窗口進(jìn)行拖動(dòng)。當(dāng)然這種實(shí)現(xiàn)的限制就是一定要透明窗口,

AllowTransparency為true或者WindowChrome的GlassFrameThickness為-1。

因?yàn)檫@種實(shí)現(xiàn)還不是很完美對(duì)裝飾器不兼容,所以提供IsWindowDragSmooth屬性,可以打開(kāi)和關(guān)閉功能。

public static bool GetIsWindowDragSmooth(DependencyObject obj)
{
    return (bool)obj.GetValue(IsWindowDragSmoothProperty);
}

???????public static void SetIsWindowDragSmooth(DependencyObject obj, bool value)
{
    obj.SetValue(IsWindowDragSmoothProperty, value);
}

/// <summary>
/// 拖拽窗口調(diào)整大小是否平滑處理,作用是避免拖拽窗口左上時(shí)右下閃爍。
/// 此屬性只對(duì)窗口有效
/// 此屬性為true時(shí)需要透明窗口才能生效,即AllowTransparency為true或者WindowChrome的GlassFrameThickness為-1。
/// 當(dāng)前版本不兼容有裝飾器的窗口,拖動(dòng)中裝飾器可能會(huì)顯示在窗口外面。
/// </summary>
// Using a DependencyProperty as the backing store for IsWindowDragSmooth.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsWindowDragSmoothProperty =
    DependencyProperty.RegisterAttached("IsWindowDragSmooth", typeof(bool), typeof(Resize), new PropertyMetadata(false));

8、拖動(dòng)事件

提供3個(gè)拖動(dòng)事件,拖動(dòng)開(kāi)始、拖動(dòng)變化、拖動(dòng)結(jié)束。

代碼示例如下:

/// <summary>
///  拖動(dòng)開(kāi)始事件
/// </summary>
public static readonly RoutedEvent DragResizeStartedEvent = EventManager.RegisterRoutedEvent("DragResizeStarted", RoutingStrategy.Direct, typeof(EventHandler<DragResizeStartedEventArgs>), typeof(Resize));
/// <summary>
/// 拖動(dòng)變化事件
/// </summary>
public static readonly RoutedEvent DragResizeDeltaEvent = EventManager.RegisterRoutedEvent("DragResizeDelta", RoutingStrategy.Direct, typeof(EventHandler<DragResizeDeltaEventArgs>), typeof(Resize));
/// <summary>
/// 拖動(dòng)結(jié)束事件
/// </summary>
public static readonly RoutedEvent DragResizeCompletedEvent = EventManager.RegisterRoutedEvent("DragResizeCompleted", RoutingStrategy.Direct, typeof(EventHandler<DragResizeCompletedEventArgs>), typeof(Resize));

9、其他功能

(1)適應(yīng)MinWidth、MinHeight

第四章完整帶的基礎(chǔ)上將邊界判斷修改為控件的MinWidth、MinHeight即可。

橫向

if (width >= minWidth/*原本是0*/)
{
    //略
}

縱向與橫向邏輯一致,修改對(duì)應(yīng)變量即可,略

(2)適應(yīng)MaxWidth、MaxHeight

超過(guò)了最大值需要進(jìn)行修正示例如下

橫向:

if (width > c.MaxWidth)
{
    if (thumb.HorizontalAlignment == HorizontalAlignment.Left)
    {
        left += width - c.MaxWidth;
        right = margin.Right;
    }
    else
    {
        left = margin.Left;
        right += width - c.MaxWidth;
    }
    width = c.MaxWidth;
}

縱向與橫向邏輯一致,修改對(duì)應(yīng)變量即可,略。

(3)適配任意dpi

所有改變坐標(biāo)以及大小的代碼已經(jīng)適配了任意dpi。

主要注意的就是PointToScreen得到的坐標(biāo)需要dpi轉(zhuǎn)換。

下列是獲取dpi的方法。

static Point GetDpiFromVisual(Visual visual)
{
    var source = PresentationSource.FromVisual(visual);
    var dpiX = 96.0;
    var dpiY = 96.0;
    if (source?.CompositionTarget != null)
    {
        dpiX = 96.0 * source.CompositionTarget.TransformToDevice.M11;
        dpiY = 96.0 * source.CompositionTarget.TransformToDevice.M22;
    }
    return new Point(dpiX, dpiY);
}

三、使用示例

0、基礎(chǔ)功能

這個(gè)是與第四章一致的基礎(chǔ)功能。

(1)、引用命名空間

Window 的其他屬性略

<Window xmlns:ac="clr-namespace:AC"/>

(2)、使用附加屬性
需要某個(gè)控件可以拖動(dòng)調(diào)整大小則

<Grid ac:Resize.IsResizeable="True" />

(3)、窗口注意事項(xiàng)

當(dāng)Window需要使用此功能時(shí)

<Window ac:Resize.IsResizeable="True" />

Window的拖動(dòng)點(diǎn)會(huì)放在子控件的裝飾層,需要注意以幾點(diǎn):

①Window必須有子控件,子控件有裝飾層(大部分控件都有裝飾層比如Grid、Border、Button等)。

②子控件不可限定大小需要,跟隨窗口大小變化。

③此功能與Window自帶的調(diào)整大小區(qū)別是,此功能可以用于無(wú)邊框窗口以及自定義拖動(dòng)點(diǎn)。

1、DragResize

DragResize需要在鼠標(biāo)左鍵按下事件中使用,對(duì)已存在的控件或者動(dòng)態(tài)生成控件使用。此方法不需要

ac:Resize.IsResizeable="True"也可以使用。

xaml

<Window x:Class="WpfResize.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:WpfResize"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        WindowStyle="None"
        ResizeMode="NoResize"
        >
    <Grid x:Name="grid" Background="SeaGreen"  MouseLeftButtonDown="Window_MouseLeftButtonDown"/>
</Window>

因?yàn)槭峭卣狗椒ǎ垣@取到控件對(duì)象直接調(diào)用DragResize即可。

cs

using AC;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

???????namespace WpfResize
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private async void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            //生成控件
            var border = new Border();
            border.Background = Brushes.Azure;
            border.Width = 0;
            border.Height = 0;
            //加入到容器
            grid.Children.Add(border);
            //拖出控件
            await border.DragResize();
            //如果寬高為0則移除
            if (border.Width == 0|| border.Height == 0)
            {
                grid.Children.Remove(border);
            }
        }
    }
}

效果預(yù)覽

注:qq錄制鼠標(biāo)出現(xiàn)了偏移

2、邊界限制

設(shè)置ac:Resize.IsResizeInBounds="True"即可。邊界限制的范圍是父控件。

xaml

<Window x:Class="WpfResize.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:WpfResize"
        xmlns:ac="clr-namespace:AC"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        WindowStyle="None"
        ResizeMode="NoResize"     
        >
    <Grid x:Name="grid" Background="SeaGreen">
        <Border BorderThickness="1" BorderBrush="White" Margin="40">
            <StackPanel>
                <Border ac:Resize.IsResizeable="True" ac:Resize.IsResizeInBounds="False" Background="White" Height="100" Width="200"  CornerRadius="10" >
                    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="不限制邊界"></TextBlock>
                </Border>
                <Border ac:Resize.IsResizeable="True" ac:Resize.IsResizeInBounds="True"  Margin="0,20,0,0" Background="White" Height="100" Width="200"  CornerRadius="10" >
                    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="限制邊界"></TextBlock>
                </Border>
            </StackPanel>
        </Border>
    </Grid>
</Window>

效果預(yù)覽

注:qq錄制鼠標(biāo)出現(xiàn)了偏移

3、交叉拖動(dòng)

通過(guò)附加屬性ac:Resize.IsAllowsCrossover設(shè)置是否交叉拖動(dòng),默認(rèn)為true。

xaml

<Window x:Class="WpfResize.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:WpfResize"
        xmlns:ac="clr-namespace:AC"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        WindowStyle="None"
        ResizeMode="NoResize"     
        >
    <Grid x:Name="grid" Background="SeaGreen">
        <StackPanel>
            <Border  Margin="0,20,0,0"  ac:Resize.IsResizeable="True" ac:Resize.IsAllowsCrossover="False"  Background="White" Height="100" Width="200"  CornerRadius="10" >
                <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="不允許交叉拖動(dòng)"></TextBlock>
            </Border>
            <Border ac:Resize.IsResizeable="True" ac:Resize.IsAllowsCrossover="True"   Margin="0,20,0,0" Background="White" Height="100" Width="200"  CornerRadius="10" >
                <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="允許交叉拖動(dòng)"></TextBlock>
            </Border>
        </StackPanel>
    </Grid>
</Window>

效果預(yù)覽

注:qq錄制鼠標(biāo)出現(xiàn)了偏移

4、拖動(dòng)點(diǎn)布局模板

通過(guò)ac:Resize.ThumbsTemplate設(shè)置拖動(dòng)點(diǎn)模板

(1)自定義圓點(diǎn)

xaml

<Window x:Class="WpfResize.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:WpfResize"
        xmlns:ac="clr-namespace:AC"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"  
        >
    <Grid x:Name="grid" Background="White">
        <Grid  Margin="0,20,0,0"  ac:Resize.IsResizeable="True" ac:Resize.IsAllowsCrossover="False"  Background="SeaGreen " Height="100" Width="200" >
            <ac:Resize.ThumbsTemplate>
                <ControlTemplate  >
                    <Border BorderBrush="Gray" BorderThickness="2" CornerRadius="8"  Background="White" Width="16" Height="16"/>
                </ControlTemplate>
            </ac:Resize.ThumbsTemplate>
            <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" Text="自定義拖動(dòng)點(diǎn)模板"></TextBlock>
        </Grid>
    </Grid>
</Window>

效果預(yù)覽

(2)4個(gè)頂點(diǎn)

xaml

<Window x:Class="WpfResize.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:WpfResize"
        xmlns:ac="clr-namespace:AC"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"  
        WindowStyle="None"
        ResizeMode="NoResize"
        >
    <Grid x:Name="grid" Background="White">
        <Grid  Margin="0,20,0,0"  ac:Resize.IsResizeable="True" ac:Resize.IsAllowsCrossover="False"  Background="SeaGreen " Height="100" Width="200" >
            <ac:Resize.ThumbsTemplate>
                <ControlTemplate >
                    <Border x:Name="brd" BorderBrush="Gray" BorderThickness="2" CornerRadius="8"  Background="White" Width="16" Height="16"/>
                    <!--通過(guò)觸發(fā)器隱藏4條邊上的點(diǎn)-->
                    <ControlTemplate.Triggers>
                        <!--左右兩條邊上的點(diǎn)-->
                        <Trigger Property="HorizontalAlignment" Value="Stretch">
                            <Setter TargetName="brd" Property="Visibility" Value="Collapsed" ></Setter>
                        </Trigger>
                        <!--上下兩條邊上的點(diǎn)-->
                        <Trigger Property="VerticalAlignment" Value="Stretch">
                            <Setter TargetName="brd" Property="Visibility" Value="Collapsed" ></Setter>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </ac:Resize.ThumbsTemplate>
            <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" Text="自定義拖動(dòng)點(diǎn)模板"></TextBlock>
        </Grid>
    </Grid>
</Window>

效果預(yù)覽

(3)單獨(dú)定制每個(gè)點(diǎn)

通過(guò)MultiTrigger觸發(fā)器來(lái)區(qū)分每個(gè)點(diǎn)。

xaml

<Window x:Class="WpfResize.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:WpfResize"
        xmlns:ac="clr-namespace:AC"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"  
        WindowStyle="None"
        ResizeMode="NoResize"
        >
    <Grid x:Name="grid" Background="White">
        <Grid  Margin="0,20,0,0"  ac:Resize.IsResizeable="True" ac:Resize.IsAllowsCrossover="False"  Background="SeaGreen" Height="100" Width="200" >
            <ac:Resize.ThumbsTemplate>
                <ControlTemplate >
                    <Border x:Name="brd" BorderBrush="Gray" BorderThickness="2" CornerRadius="8"  Background="White" Width="16" Height="16"/>
                    <ControlTemplate.Triggers>
                         <!--左上-->
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="HorizontalAlignment" Value="Left" ></Condition>
                                <Condition Property="VerticalAlignment" Value="Top" ></Condition>
                            </MultiTrigger.Conditions>
                            <Setter TargetName="brd" Property="BorderBrush" Value="Aqua"></Setter>
                        </MultiTrigger>
                        <!--右上-->
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="HorizontalAlignment" Value="Right" ></Condition>
                                <Condition Property="VerticalAlignment" Value="Top" ></Condition>
                            </MultiTrigger.Conditions>
                            <Setter TargetName="brd" Property="BorderBrush" Value="DarkGoldenrod"></Setter>
                        </MultiTrigger>
                        <!--右下-->
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="HorizontalAlignment" Value="Right" ></Condition>
                                <Condition Property="VerticalAlignment" Value="Bottom" ></Condition>
                            </MultiTrigger.Conditions>
                            <Setter TargetName="brd" Property="BorderBrush" Value="DeepPink"></Setter>
                        </MultiTrigger>
                        <!--左下-->
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="HorizontalAlignment" Value="Left" ></Condition>
                                <Condition Property="VerticalAlignment" Value="Bottom" ></Condition>
                            </MultiTrigger.Conditions>
                            <Setter TargetName="brd" Property="BorderBrush" Value="Red"></Setter>
                        </MultiTrigger>
                        <!--上-->
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="HorizontalAlignment" Value="Stretch" ></Condition>
                                <Condition Property="VerticalAlignment" Value="Top" ></Condition>
                            </MultiTrigger.Conditions>
                            <Setter TargetName="brd" Property="BorderBrush" Value="Gold"></Setter>
                        </MultiTrigger>
                        <!--下-->
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="HorizontalAlignment" Value="Stretch" ></Condition>
                                <Condition Property="VerticalAlignment" Value="Bottom" ></Condition>
                            </MultiTrigger.Conditions>
                            <Setter TargetName="brd" Property="BorderBrush" Value="Indigo"></Setter>
                        </MultiTrigger>
                        <!--左-->
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="HorizontalAlignment" Value="Left" ></Condition>
                                <Condition Property="VerticalAlignment" Value="Stretch" ></Condition>
                            </MultiTrigger.Conditions>
                            <Setter TargetName="brd" Property="BorderBrush" Value="Blue"></Setter>
                        </MultiTrigger>
                        <!--右-->
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="HorizontalAlignment" Value="Right" ></Condition>
                                <Condition Property="VerticalAlignment" Value="Stretch" ></Condition>
                            </MultiTrigger.Conditions>
                            <Setter TargetName="brd" Property="BorderBrush" Value="Green"></Setter>
                        </MultiTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </ac:Resize.ThumbsTemplate>
            <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" Text="自定義拖動(dòng)點(diǎn)模板"></TextBlock>
        </Grid>
    </Grid>
</Window>

效果預(yù)覽

5、拖動(dòng)點(diǎn)容器模板

通過(guò)ac:Resize.ThumbsPanel設(shè)置拖動(dòng)點(diǎn)容器模板,主要作用是設(shè)置margin,方便調(diào)整拖動(dòng)點(diǎn)的偏移。

默認(rèn)的容器有Margin="-3"的偏移。

(1)無(wú)Margin

此示例是為了說(shuō)明無(wú)Margin的情況。

xaml

<Window x:Class="WpfResize.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:WpfResize"
        xmlns:ac="clr-namespace:AC"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"  
        WindowStyle="None"
        ResizeMode="NoResize"
        >
    <Grid x:Name="grid" Background="White">
        <Grid  Margin="0,20,0,0"  ac:Resize.IsResizeable="True" ac:Resize.IsAllowsCrossover="False"  Background="SeaGreen " Height="100" Width="200" >
            <ac:Resize.ThumbsTemplate>
                <ControlTemplate >
                    <Border x:Name="brd" BorderBrush="Gray" BorderThickness="2" CornerRadius="8"  Background="White" Width="16" Height="16"/>
                </ControlTemplate>
            </ac:Resize.ThumbsTemplate>
            <ac:Resize.ThumbsPanel>
                <ItemsPanelTemplate>
                    <Grid></Grid>
                </ItemsPanelTemplate>
            </ac:Resize.ThumbsPanel>
            <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" Text="自定義拖點(diǎn)容器模板"></TextBlock>
        </Grid>
    </Grid>
</Window>

效果預(yù)覽

(2)設(shè)置Margin

Margin設(shè)置為拖動(dòng)點(diǎn)的一半大小就剛好在邊線中間。

xaml

<Window x:Class="WpfResize.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:WpfResize"
        xmlns:ac="clr-namespace:AC"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"  
        WindowStyle="None"
        ResizeMode="NoResize"
        >
    <Grid x:Name="grid" Background="White">
        <Grid  Margin="0,20,0,0"  ac:Resize.IsResizeable="True" ac:Resize.IsAllowsCrossover="False"  Background="SeaGreen " Height="100" Width="200" >
            <ac:Resize.ThumbsTemplate>
                <ControlTemplate >
                    <Border x:Name="brd" BorderBrush="Gray" BorderThickness="2" CornerRadius="8"  Background="White" Width="16" Height="16"/>
                </ControlTemplate>
            </ac:Resize.ThumbsTemplate>
            <ac:Resize.ThumbsPanel>
                <ItemsPanelTemplate>
                    <Grid Margin="-8"></Grid>
                </ItemsPanelTemplate>
            </ac:Resize.ThumbsPanel>
            <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" Text="自定義拖點(diǎn)容器模板"></TextBlock>
        </Grid>
    </Grid>
</Window>

效果預(yù)覽

6、整體模板

設(shè)置整體模板Template后會(huì)覆蓋拖動(dòng)點(diǎn)模板和拖動(dòng)點(diǎn)布局模板。規(guī)則是第一級(jí)控件為容器、第二級(jí)控件為T(mén)humb類(lèi)型自動(dòng)識(shí)別為拖動(dòng)點(diǎn),拖動(dòng)方向由HorizontalAlignment和VerticalAlignment決定, 即可以有任意個(gè)拖動(dòng)點(diǎn)Thumb,也可以放任意其他控件。

<Window x:Class="WpfResize.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:WpfResize"
        xmlns:ac="clr-namespace:AC"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"  
        WindowStyle="None"
        ResizeMode="NoResize"
        >
    <Grid x:Name="grid" Background="White">
        <Grid  Margin="0,20,0,0"  ac:Resize.IsResizeable="True"   Background="SeaGreen " Height="100" Width="200" >
            <ac:Resize.Template>
                <ControlTemplate >
                    <Grid  Margin="-4">
                        <Grid.Resources>
                            <Style TargetType="Thumb">
                                <Setter Property="Width" Value="8"></Setter>
                                <Setter Property="Height" Value="8"></Setter>
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate>
                                            <Border  Background="Aqua"></Border>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </Grid.Resources>
                        <Border BorderBrush="Aqua"  BorderThickness="2" Margin="4"></Border>
                            <!--左-->
                        <Thumb   HorizontalAlignment="Left"  Cursor="SizeWE"/>
                        <!--上-->
                        <Thumb   VerticalAlignment="Top" Cursor="SizeNS"/>
                        <!--右-->
                        <Thumb   HorizontalAlignment="Right"  Cursor="SizeWE"/>
                        <!--下-->
                        <Thumb    VerticalAlignment="Bottom" Cursor="SizeNS"/>
                        <!--左上-->
                        <Thumb    HorizontalAlignment="Left" VerticalAlignment="Top" Cursor="SizeNWSE"/>
                        <!--右上-->
                        <Thumb    HorizontalAlignment="Right" VerticalAlignment="Top"  Cursor="SizeNESW"/>
                        <!--右下-->
                        <Thumb    HorizontalAlignment="Right" VerticalAlignment="Bottom"  Cursor="SizeNWSE"/>
                        <!--左下-->
                        <Thumb    HorizontalAlignment="Left" VerticalAlignment="Bottom" Cursor="SizeNESW"/>
                    </Grid>
                </ControlTemplate>
            </ac:Resize.Template>
            <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" Text="自定義整體模板"></TextBlock>
        </Grid>
    </Grid>
</Window>

效果預(yù)覽

7、窗口平滑拖動(dòng)

窗口為透明窗口(AllowTransparency為true或者WindowChrome的GlassFrameThickness為-1),附加屬性 ac:Resize.IsWindowDragSmooth設(shè)置為true即可以實(shí)現(xiàn)平滑拖動(dòng)。

注:當(dāng)前版本和裝飾器不兼容,拖動(dòng)時(shí)裝飾器可能顯示在窗口外面,謹(jǐn)慎使用此屬性

<Window x:Class="WpfResize.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:WpfResize"
        xmlns:ac="clr-namespace:AC"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"  
        WindowStyle="None"
        ResizeMode="NoResize"
        AllowsTransparency="True"
        ac:Resize.IsResizeable="True"
        ac:Resize.IsWindowDragSmooth="True"
        >
    <Grid Background="SeaGreen "/>
</Window>

作為對(duì)比先展示非平滑拖動(dòng)

注:qq錄制鼠標(biāo)出現(xiàn)了偏移

設(shè)置平滑拖動(dòng)效果預(yù)覽

注:qq錄制鼠標(biāo)出現(xiàn)了偏移

8、拖動(dòng)事件

3個(gè)事件,拖動(dòng)開(kāi)始ac:Resize.DragResizeStarted、拖動(dòng)變化ac:Resize.DragResizeDelta、拖動(dòng)結(jié)束ac:Resize.DragResizeCompleted

xaml

<Window x:Class="WpfResize.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:WpfResize"
        xmlns:ac="clr-namespace:AC"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"  
        >
    <Grid Background="SeaGreen ">
        <Border Background="Aqua" Width="200" Height="200"   ac:Resize.IsResizeable="True"  ac:Resize.DragResizeStarted="Border_DragResizeStarted"  ac:Resize.DragResizeCompleted="Border_DragResizeCompleted" ac:Resize.DragResizeDelta="Border_DragResizeDelta"></Border>
    </Grid>
</Window>

cs

using AC;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace WpfResize
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Border_DragResizeStarted(object sender, DragResizeStartedEventArgs e)
        {
            Console.WriteLine("開(kāi)始拖動(dòng)");
        }

        private void Border_DragResizeCompleted(object sender, DragResizeCompletedEventArgs e)
        {
            Console.WriteLine("結(jié)束拖動(dòng)");
        }

???????        private void Border_DragResizeDelta(object sender, DragResizeDeltaEventArgs e)
        {
            Console.WriteLine("橫向變化:"+e.HorizontalChange+ " 縱向變化:"+e.VerticalChange+ " 寬變化:" + e.WidthChange + " 高變化:" + e.HeightChange);
        }
    }
}

效果預(yù)覽

注:qq錄制鼠標(biāo)出現(xiàn)了偏移

9、其他功能

(1)適應(yīng)MinWidth、MinHeight

xaml

<Window x:Class="WpfResize.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:WpfResize"
        xmlns:ac="clr-namespace:AC"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"  
        >
    <Grid Background="SeaGreen ">
        <Border Background="Aqua" MinWidth="100" MinHeight="100" Width="200" Height="200"   ac:Resize.IsResizeable="True"  ></Border>
    </Grid>
</Window>

效果預(yù)覽

注:qq錄制鼠標(biāo)出現(xiàn)了偏移

(2)適應(yīng)MaxWidth、MaxHeight

xaml

<Window x:Class="WpfResize.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:WpfResize"
        xmlns:ac="clr-namespace:AC"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"  
        >
    <Grid Background="SeaGreen ">
        <Border Background="Aqua" MaxWidth="200" MaxHeight="200" Width="100" Height="100"   ac:Resize.IsResizeable="True"  ></Border>
    </Grid>
</Window>

效果預(yù)覽

總結(jié)

拓展后的功能更加全面以及兼容性更強(qiáng)了,比如DragRezie就可以用于畫(huà)板,邊界限制也是比較實(shí)用的功能,拖動(dòng)點(diǎn)模板簡(jiǎn)化了自定義的難度,拖動(dòng)事件可以用于實(shí)現(xiàn)撤銷(xiāo)重做功能,窗口平滑拖動(dòng)優(yōu)化了使用體驗(yàn)。但是還是有些功能不夠完,需要后期繼續(xù)優(yōu)化??偟膩?lái)說(shuō),本文實(shí)現(xiàn)的拖動(dòng)調(diào)整大小模塊已經(jīng)變得更加方便實(shí)用,后期還會(huì)繼續(xù)完善優(yōu)化。

以上就是C# wpf實(shí)現(xiàn)任意控件更多調(diào)整大小功能的詳細(xì)內(nèi)容,更多關(guān)于C# wpf控件調(diào)整的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論