Search code examples
c#wpfparameter-passingadorner

Exchange parameters between adorner and adorned control


I need to pass some parameters between adorner and adorned control.

How this can be done? Should I remove and add new adorner with new parameters every time parameters change?

For example, one of my parameters:

    public static readonly DependencyProperty ThetaProperty =
        DependencyProperty.Register("Theta", typeof (double), typeof (SplitControl), new PropertyMetadata(default(double), SetTheta));

    public double Theta
    {
        get { return (double) GetValue(ThetaProperty); }
        set { SetValue(ThetaProperty, value); }
    }

    private static void SetTheta(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        _adorner.Theta = (double) e.NewValue;
    }

In adorner Theta:

    public double Theta
    {
        get
        {
            return (Math.Atan(((_middleTop - _middleBottom) / AdornedElement.DesiredSize.Height))) * 180 / Math.PI;
        }
        set
        {
            double deltaX = (Math.Tan((Math.PI/180)*value))*(AdornedElement.DesiredSize.Height/2);
            _middleTop = _middle + deltaX;
            _middleBottom = _middle - deltaX;
        }
    }

Solution

  • Here's a sample (type something into the textbox and watch the adorner):

    Code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Globalization;
    
    namespace Adorners
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
                this.Loaded += (o, e) => 
                {
                    AdornerLayer layer = AdornerLayer.GetAdornerLayer(this.t);
    
                    MyAdorner myAdorner = new MyAdorner(this.t);
    
                    layer.Add(myAdorner);
    
                    this.t.Text = "Modified Value";
                };
            }
        }
    
    
        public class MyAdorner : Adorner
        {
            public static DependencyProperty TextProperty =
                DependencyProperty.Register("Text",
                typeof(string),
                typeof(MyAdorner),
                new PropertyMetadata("Default Text", 
                (o, e) => 
                {
                    ((MyAdorner)o).InvalidateVisual();
                }));
    
            // Be sure to call the base class constructor.
            public MyAdorner(UIElement adornedElement)
                : base(adornedElement)
            {
                this.DataContext = this.AdornedElement;
    
                this.SetUpBindings();
            }
    
            private void SetUpBindings()
            {
                BindingOperations.SetBinding(this,
                   MyAdorner.TextProperty,
                   new Binding()
                   {
                       Path = new PropertyPath("Text"),
                       UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
                   });
            }
    
            public string Text
            {
                get { return (string)this.GetValue(MyAdorner.TextProperty); }
                set { this.SetValue(MyAdorner.TextProperty, value); }
            }
    
            protected override void OnRender(DrawingContext drawingContext)
            {
                Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);
    
                drawingContext.DrawText(new FormattedText(this.Text, CultureInfo.CurrentCulture, 
                    FlowDirection.LeftToRight, 
                    new Typeface("Arial"), 
                    20, 
                    Brushes.Black), 
                    new Point(0, 150));
            }
        }
    }
    

    Markup:

    <Window x:Class="Adorners.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid x:Name="AdornedGrid">
            <TextBox x:Name="t" Width="200" Height="100" Background="Green"></TextBox>
        </Grid>
    </Window>