zoukankan      html  css  js  c++  java
  • 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]); ;
                }
            }
  • 相关阅读:
    RTP/RTSP编程
    makefile
    VS 2010内存泄漏检测
    Linux Shell中捕获CTRL+C
    const
    Hdu 5344
    Hdu5762
    CF1200C
    CF1200B
    CF1200A
  • 原文地址:https://www.cnblogs.com/T-ARF/p/11062730.html
Copyright © 2011-2022 走看看