1. 程式人生 > WINDOWS開發 >WPF Adorner 彈出式工具欄 例子

WPF Adorner 彈出式工具欄 例子

原文:WPF Adorner 彈出式工具欄 例子

源於MSDN 一個問題。

問:如何做出類似word的文字選中後工具欄彈出和動畫效果。

我用的是adorner,其實用popup也是可以的。

效果圖:

技術分享圖片

中間黑色部分代表真正的工具欄。

xaml程式碼:

技術分享圖片
<Window x:Class="ADO_TOOL.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:ADO_TOOL" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid x:Name="adohost"> <RichTextBox LostKeyboardFocus="
RTB_LostKeyboardFocus" VerticalAlignment="Center" x:Name="RTB" PreviewMouseLeftButtonUp="RichTextBox_PreviewMouseLeftButtonUp" > <FlowDocument > <Paragraph > <Run Text="測試顯示tool"/> </Paragraph> </FlowDocument> </RichTextBox> </Grid> </Window>
技術分享圖片

adoner程式碼類

技術分享圖片
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;

namespace ADO_TOOL
{
    public class ado_Gird : Adorner
    {

        private VisualCollection collection;

        protected override int VisualChildrenCount => collection.Count;


        protected override Visual GetVisualChild(int index) => collection[index];


        protected override Size MeasureOverride(Size constraint) => base.MeasureOverride(constraint);

        protected override Size ArrangeOverride(Size finalSize)
        {

            _gird.Arrange(new Rect(finalSize));

            var f = host as FrameworkElement;

            _gird.Margin = new Thickness(left,0-top-_gird.Height,0,0);
           
           return base.ArrangeOverride(finalSize);

        }
        private  Grid _gird;

        private UIElement host;

        private double left;
        private double top;

        public   ado_Gird(UIElement adornedElement,double left,double top) :this(adornedElement)
        {
            this.left= left;
            this.top = top;
        }

        //h1是外部grid-內部grid的平均高度
        //h2是外部grid-內部grid的平均寬度
        readonly int h1 = 20,h2=24;
        public ado_Gird(UIElement adornedElement) : base(adornedElement)
        {
            collection = new VisualCollection(this);
            host = adornedElement;
            this._gird = new Grid();

            _gird.Height = 50;

            _gird.Width = 128;

            _gird.HorizontalAlignment = HorizontalAlignment.Left;

            _gird.Background = new SolidColorBrush(Colors.Red);

            Grid g2 = new Grid();

            g2.Height = 10;

            g2.Width = 80;

            g2.Background = new SolidColorBrush(Colors.Black);

            _gird.Children.Add(g2);

            _gird.MouseMove += _gird_MouseMove;

            _gird.MouseLeave += _gird_MouseLeave;

            _gird.Opacity = 0.5;
     
            collection.Add(_gird);
        }

        private void _gird_MouseLeave(object sender,System.Windows.Input.MouseEventArgs e)
        {
            _gird.Opacity = 0.1;
        }

        private void _gird_MouseMove(object sender,System.Windows.Input.MouseEventArgs e)
        {
            var point = e.GetPosition(_gird);
            var f = host as FrameworkElement;
            if (_gird.Width - point.X <= h2)
            {
                  _gird.Opacity = 1-((h2 -( _gird.Width - point.X)) / h2);
            }
            if(_gird.Height - point.Y <= h1)
            {
                _gird.Opacity = 1 - ((h1 - (_gird.Height - point.Y)) / h1);
            }
            if (point.X>0&&point.X<=h2)
            {
                _gird.Opacity = 1-((h2 - point.X) / h2);
            }
            if (point.Y > 0 && point.Y <= h1)
            {
               _gird.Opacity = 1 - (h1 - point.Y) / h1;
            }
            
        }
    }
}
技術分享圖片

xaml.cs頁面程式碼:

技術分享圖片
AdornerLayer layer;
        private void RichTextBox_PreviewMouseLeftButtonUp(object sender,MouseButtonEventArgs e)
        {
            var point = e.GetPosition(RTB);
            if (layer != null)
            {
                var b = layer.GetAdorners(adohost);
                if(b!=null)
                if(b.Count()>0)
                   layer.Remove(b[0]);
            }
            layer = AdornerLayer.GetAdornerLayer(adohost);
            var ado = new ado_Gird(adohost,point.X,RTB.ActualHeight);
            layer.Add(ado);
        }     

        private void RTB_LostKeyboardFocus(object sender,KeyboardFocusChangedEventArgs e)
        {
           
            if (layer != null)
            {
                var b = layer.GetAdorners(adohost);
                if (b != null)
                    if (b.Count() > 0)
                    layer.Remove(b[0]); ;
            }
        }
技術分享圖片