gpt4 book ai didi

wpf - 在 WPF 中相对于父级尺寸定位装饰器

转载 作者:行者123 更新时间:2023-12-04 16:03:09 24 4
gpt4 key购买 nike

我试图根据装饰元素的父元素的尺寸来定位一个装饰器。例如,我有一个文本框。我想装饰这个文本框,使它看起来像这样:

how the adorner needs to be placed http://img707.imageshack.us/img707/9840/fig1.png

文本框放置在 Canvas 对象中,如果有足够的可用空间,则将装饰器(半透明圆角正方形)与文本框的底部边缘对齐。当用户点击文本框时,装饰器被启动。

当前, Canvas 及其内容(文本框)托管在 WinForms 表单中 - 因此 WPF 由 ElementHost 控件处理。

但是当我运行我的代码时,当第一次单击文本框时,它会显示与文本框顶部边缘对齐的装饰器(见下图)。之后它正确定位自己(如上图)有谁知道为什么会这样?

how adorner is positions http://img14.imageshack.us/img14/4766/fig2v.png

我在下面粘贴了代码:

TextBoxAdorner.cs - 这是装饰器逻辑

public class TextBoxAdorner : Adorner
{
private TextBox _adornedElement;
private VisualCollection _visualChildren;
private Rectangle _shape;
private Canvas _container;
private Canvas _parentCanvas;

public TextBoxAdorner(UIElement adornedElement, Canvas parentCanvas)
: base(adornedElement)
{
_adornedElement = (TextBox)adornedElement;
_parentCanvas = parentCanvas;
_visualChildren = new VisualCollection(this);

_container = new Canvas();

_shape = new Rectangle();
_shape.Width = 100;
_shape.Height = 80;
_shape.Fill = Brushes.Blue;
_shape.Opacity = 0.5;

_container.Children.Add(_shape);

_visualChildren.Add(_container);
}

protected override Size ArrangeOverride(Size finalSize)
{
Point location = GetLocation();
_container.Arrange(new Rect(location, finalSize));

return finalSize;
}

private Point GetLocation()
{
if (_parentCanvas == null)
return new Point(0, 0);

Point translate;
double xloc = 0, yloc = _shape.Height - _adornedElement.ActualHeight;

if (yloc < 0) // textbox is bigger than the shape
yloc = 0;
else
{
translate = this.TranslatePoint(new Point(0, -yloc), _parentCanvas);

// coordinate is beyond the position of the parent canvas
if (translate.Y < 0) // this is true the first time it's run
yloc = 0;
else
yloc = -yloc;
}

translate = this.TranslatePoint(new Point(_shape.Width, 0), _parentCanvas);

// textbox is in right edge of the canvas
if (translate.X > _parentCanvas.ActualWidth)
{
double pos = translate.X - _parentCanvas.ActualWidth;

translate = this.TranslatePoint(new Point(-pos,0), _parentCanvas);

if (translate.X < 0)
xloc = 0;
else
xloc = translate.X;
}

return new Point(xloc, yloc);
}

protected override Size MeasureOverride(Size constraint)
{
Size myConstraint = new Size(_shape.Width, _shape.Height);
_container.Measure(myConstraint);

return _container.DesiredSize;
}

protected override Visual GetVisualChild(int index)
{
return _visualChildren[index];
}

protected override int VisualChildrenCount
{
get
{
return _visualChildren.Count;
}
}
}

最佳答案

Adorner 的位置是相对于被装饰元素的。如果您希望它位于对象的顶部,则 yloc 的值应该是负面的。但是,您拥有的代码也考虑了 Canvas 的边界。如果上面的矩形没有足够的地方,它就会把它放在下面。尝试将 TextBox 放在 Canvas 中稍低的位置。

关于wpf - 在 WPF 中相对于父级尺寸定位装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2003805/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com