gpt4 book ai didi

c# - WPF 自定义框架元素/IScrollInfo

转载 作者:行者123 更新时间:2023-11-30 17:19:15 28 4
gpt4 key购买 nike

我有一个简单的测试应用程序,其中包含基本的自定义 FrameworkElement 实现(下面的 TestElement)。 TestElement 创建了几个绘图视觉对象,并在构造函数中绘制了一些宽度为 600 的东西。它还实现了 IScrollinfo 的必要位;包含该元素的窗口有一个滚动查看器,最大尺寸为 300x300。滚动条出现但不滚动 TestElement 的内容。

任何人都可以建议我尝试做的事情是否可行,如果可行,我做错了什么。我可以在 SetHorizo​​ntalOffset 中重新渲染绘图视觉效果,但出于性能原因不想这样做,因为我已经绘制了我需要的所有内容。

我希望这个问题有一定道理 - 如果没有,请告诉我,我可以澄清。

非常感谢 - 卡尔

public class TestElement : FrameworkElement, IScrollInfo
{
DrawingVisual visual;
DrawingVisual visual2;
public TestElement()
{
Draw();
this.MaxWidth = 600;
this.MaxHeight = 300;
}
public void Draw()
{
if(visual == null)
{
visual = new DrawingVisual();
base.AddVisualChild(visual);
base.AddLogicalChild(visual);
}
if (visual2 == null)
{
visual2 = new DrawingVisual();
base.AddVisualChild(visual2);
base.AddLogicalChild(visual2);
}
Random rand = new Random();
var pen = new Pen(Brushes.Black, 1);
using(var dc = visual.RenderOpen())
{
for (int i = 0; i < 400; i++)
{
var r = rand.Next(10, 200);
dc.DrawLine(pen, new Point(i, r), new Point(i, 0));
}
}
using (var dc = visual2.RenderOpen())
{
for (int i = 0; i < 200; i++)
{
var r = rand.Next(10, 200);
dc.DrawLine(pen, new Point(i, r), new Point(i, 0));
}
visual2.Offset = new Vector(400, 0);
}
}
protected override int VisualChildrenCount
{
get { return 2; }
}
protected override Visual GetVisualChild(int index)
{
return index == 0 ? visual : visual2;
}
protected override Size MeasureOverride(Size availableSize)
{
viewport = availableSize;
owner.InvalidateScrollInfo();
return base.MeasureOverride(availableSize);
}
protected override Size ArrangeOverride(Size finalSize)
{
var value = base.ArrangeOverride(finalSize);
return base.ArrangeOverride(finalSize);
}


Point offset = new Point(0,0);
public void SetHorizontalOffset(double offset)
{
this.offset.X = offset;
this.InvalidateArrange();
}

public void SetVerticalOffset(double offset)
{
this.offset.Y = offset;
}

public Rect MakeVisible(Visual visual, Rect rectangle)
{
throw new NotImplementedException();
}

public bool CanVerticallyScroll { get; set; }
public bool CanHorizontallyScroll { get; set; }

Size extent = new Size(600, 300);

private Size viewport = new Size(0, 0);
public double ExtentWidth
{
get { return extent.Width; }
}

public double ExtentHeight
{
get {return extent.Height; }
}

public double ViewportWidth
{
get { return viewport.Width; }
}

public double ViewportHeight
{
get { return viewport.Height; }
}

public double HorizontalOffset
{
get { return offset.X; }
}

public double VerticalOffset
{
get { return offset.Y; }
}

private ScrollViewer owner;

public ScrollViewer ScrollOwner
{
get { return owner; }
set { owner = value; }
}


}

xaml:

<Window x:Class="TestWpfApp.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l ="clr-namespace:TestWpfApp"
Title="TestWpfApp" Height="300" Width="300" >
<Grid>
<ScrollViewer CanContentScroll="True" HorizontalScrollBarVisibility="Visible">
<l:TestElement CanHorizontallyScroll="True" />
</ScrollViewer>
</Grid>

最佳答案

刚刚也喝了一杯啤酒,这有助于找到解决方案。 ;-)

这不是最终的“一切都做得很好”的解决方案,但肯定会进一步帮助您:

在您的 ArrangeOverride 实现中,尝试:

protected override Size ArrangeOverride(Size finalSize)
{
this.visual.Offset = new Vector(-this.HorizontalOffset, -this.VerticalOffset);

var value = base.ArrangeOverride(finalSize);
return base.ArrangeOverride(finalSize);
}

基本上您必须自己移动对象。

有关更多信息,请参阅这篇文章:iscrollinfo tutorial.通常,您必须使用 Transformations 将对象移动到您滚动它们的位置。

关于c# - WPF 自定义框架元素/IScrollInfo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5120462/

28 4 0
文章推荐: c# - 用C#写的com server对象能不能在客户端释放的时候立即发现?
文章推荐: c# - 复选框序列化
文章推荐: c# - 检查子重复项
文章推荐: javascript - jQuery 使用 .find() 方法获取具有不同类的 的内部