如何在 MouseHit 上更改 DrawingVisual 的颜色
How to change color of a DrawingVisual on MouseHit
以下代码改编自 Adam Nathan 发布的 WPF 4.5 第 502 页的代码示例。
按照那里的建议,我创建了一个 class VisualHostClass
来“托管”DrawingVisual 列表,从而使它们可以显示。这到目前为止有效。
现在我想通过更改显示视觉对象的颜色来响应鼠标左键单击。代码在方法 HitTestCallback
.
中
通过包含的 Trace.WriteLine 语句,我可以看到相关行
drw.Brush = Brushes.Red;
达到 之后 属性 Brush 有了新的值。 但是:显示没有变化,点击后的DrawingVisual还是黄色(创建时使用的画笔颜色)
can/should 我在这里做什么? (我绝对是 WPF 的初学者)。
提前感谢所有的回答!
public partial class VisualHostClass : FrameworkElement
{
public VisualHostClass()
{
}
public List<DrawingVisual> myVisuals = new List<DrawingVisual>();
public void AddVisual(DrawingVisual dvs)
{
myVisuals.Add(dvs);
AddVisualChild(dvs);
AddLogicalChild(dvs);
}
protected override int VisualChildrenCount
{
get { return myVisuals.Count; }
}
protected override Visual GetVisualChild(int index)
{
if (index < 0 || index >= myVisuals.Count)
{
throw new ArgumentOutOfRangeException("index");
}
return myVisuals[index];
}
public void removeAllChilds()
{
foreach (DrawingVisual dvs in myVisuals)
{
RemoveVisualChild(dvs);
RemoveLogicalChild(dvs);
}
myVisuals.Clear();
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
Point location = e.GetPosition(this);
VisualTreeHelper.HitTest(this, null,
new HitTestResultCallback(HitTestCallback),
new PointHitTestParameters(location));
}
public HitTestResultBehavior HitTestCallback(HitTestResult result)
{
if (result.VisualHit.GetType() == typeof(DrawingVisual))
{
DrawingVisual dv = result.VisualHit as DrawingVisual;
Trace.WriteLine("HitTestCallback: dv = " + dv.ToString());
foreach(GeometryDrawing drw in dv.Drawing.Children)
{
Trace.WriteLine("HitTestCallback: drw = " + drw.ToString());
Trace.WriteLine("HitTestCallback: drw.Geometry = " + drw.Geometry.ToString());
Trace.WriteLine("HitTestCallback: drw.Brush = " + drw.Brush.ToString());
drw.Brush = Brushes.Red;
Trace.WriteLine("HitTestCallback: drw.Brush = " + drw.Brush.ToString());
Trace.WriteLine("HitTestCallback: drw.IsFrozen = " + drw.IsFrozen.ToString());
}
}
return HitTestResultBehavior.Continue;
}
}
}
编辑:经过一些实验后,下面的工作(但它对我来说并不令人满意,因为我只能更改 SolidColorBrush
的 Color
,但不能更改 Brush
本身):
public void ChangeBrush(DrawingVisual dv)
{
Trace.WriteLine("HitTestCallback: dv = " + dv.ToString());
foreach (Drawing drw1 in dv.Drawing.Children)
{
if (drw1 is GeometryDrawing)
{
GeometryDrawing drw = drw1 as GeometryDrawing;
Trace.WriteLine("HitTestCallback: drw = " + drw.ToString());
Trace.WriteLine("HitTestCallback: drw.Geometry = " + drw.Geometry.ToString());
Trace.WriteLine("HitTestCallback: drw.Brush = " + drw.Brush.ToString());
Trace.WriteLine("HitTestCallback: drw.IsFrozen = " + drw.IsFrozen.ToString());
Trace.WriteLine("HitTestCallback: drw.Brush.IsFrozen = " + drw.Brush.IsFrozen.ToString());
// does not work
//SolidColorBrush newBrush = new SolidColorBrush(Colors.Red);
//newBrush.Freeze();
//drw.Brush = newBrush;
// works with drw.Brush already containing a SolidColorBrush
(drw.Brush as SolidColorBrush).Color =
(drw.Brush as SolidColorBrush).Color == Colors.LightGoldenrodYellow ?
Colors.Red : Colors.LightGoldenrodYellow;
Trace.WriteLine("HitTestCallback: drw.Brush = " + drw.Brush.ToString());
Trace.WriteLine("HitTestCallback: drw.IsFrozen = " + drw.IsFrozen.ToString());
Trace.WriteLine("HitTestCallback: drw.Brush.IsFrozen = " + drw.Brush.IsFrozen.ToString());
}
}
}
为了记录,我引用了构造 DrawingVisual
的代码并放入 VisualHostClass
PathGeometry pgnGeom = RenderPolygonWithHoles2Geometry(pgn);
DrawingVisual dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{
SolidColorBrush brush1 = new SolidColorBrush(Colors.LightGoldenrodYellow);
dc.DrawGeometry(brush1, null, pgnGeom);
}
myVisualHost.AddVisual(dv);
看来 dc.DrawGeometry(...)
创建的绘图已冻结,即不可修改。
传递我自己的绘图对我有用:
using (var dc = dv.RenderOpen())
{
dc.DrawDrawing(new GeometryDrawing(Brushes.LightGoldenrodYellow, null, pgnGeom));
}
以下代码改编自 Adam Nathan 发布的 WPF 4.5 第 502 页的代码示例。
按照那里的建议,我创建了一个 class VisualHostClass
来“托管”DrawingVisual 列表,从而使它们可以显示。这到目前为止有效。
现在我想通过更改显示视觉对象的颜色来响应鼠标左键单击。代码在方法 HitTestCallback
.
通过包含的 Trace.WriteLine 语句,我可以看到相关行
drw.Brush = Brushes.Red;
达到 之后 属性 Brush 有了新的值。 但是:显示没有变化,点击后的DrawingVisual还是黄色(创建时使用的画笔颜色)
can/should 我在这里做什么? (我绝对是 WPF 的初学者)。
提前感谢所有的回答!
public partial class VisualHostClass : FrameworkElement
{
public VisualHostClass()
{
}
public List<DrawingVisual> myVisuals = new List<DrawingVisual>();
public void AddVisual(DrawingVisual dvs)
{
myVisuals.Add(dvs);
AddVisualChild(dvs);
AddLogicalChild(dvs);
}
protected override int VisualChildrenCount
{
get { return myVisuals.Count; }
}
protected override Visual GetVisualChild(int index)
{
if (index < 0 || index >= myVisuals.Count)
{
throw new ArgumentOutOfRangeException("index");
}
return myVisuals[index];
}
public void removeAllChilds()
{
foreach (DrawingVisual dvs in myVisuals)
{
RemoveVisualChild(dvs);
RemoveLogicalChild(dvs);
}
myVisuals.Clear();
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
Point location = e.GetPosition(this);
VisualTreeHelper.HitTest(this, null,
new HitTestResultCallback(HitTestCallback),
new PointHitTestParameters(location));
}
public HitTestResultBehavior HitTestCallback(HitTestResult result)
{
if (result.VisualHit.GetType() == typeof(DrawingVisual))
{
DrawingVisual dv = result.VisualHit as DrawingVisual;
Trace.WriteLine("HitTestCallback: dv = " + dv.ToString());
foreach(GeometryDrawing drw in dv.Drawing.Children)
{
Trace.WriteLine("HitTestCallback: drw = " + drw.ToString());
Trace.WriteLine("HitTestCallback: drw.Geometry = " + drw.Geometry.ToString());
Trace.WriteLine("HitTestCallback: drw.Brush = " + drw.Brush.ToString());
drw.Brush = Brushes.Red;
Trace.WriteLine("HitTestCallback: drw.Brush = " + drw.Brush.ToString());
Trace.WriteLine("HitTestCallback: drw.IsFrozen = " + drw.IsFrozen.ToString());
}
}
return HitTestResultBehavior.Continue;
}
}
}
编辑:经过一些实验后,下面的工作(但它对我来说并不令人满意,因为我只能更改 SolidColorBrush
的 Color
,但不能更改 Brush
本身):
public void ChangeBrush(DrawingVisual dv)
{
Trace.WriteLine("HitTestCallback: dv = " + dv.ToString());
foreach (Drawing drw1 in dv.Drawing.Children)
{
if (drw1 is GeometryDrawing)
{
GeometryDrawing drw = drw1 as GeometryDrawing;
Trace.WriteLine("HitTestCallback: drw = " + drw.ToString());
Trace.WriteLine("HitTestCallback: drw.Geometry = " + drw.Geometry.ToString());
Trace.WriteLine("HitTestCallback: drw.Brush = " + drw.Brush.ToString());
Trace.WriteLine("HitTestCallback: drw.IsFrozen = " + drw.IsFrozen.ToString());
Trace.WriteLine("HitTestCallback: drw.Brush.IsFrozen = " + drw.Brush.IsFrozen.ToString());
// does not work
//SolidColorBrush newBrush = new SolidColorBrush(Colors.Red);
//newBrush.Freeze();
//drw.Brush = newBrush;
// works with drw.Brush already containing a SolidColorBrush
(drw.Brush as SolidColorBrush).Color =
(drw.Brush as SolidColorBrush).Color == Colors.LightGoldenrodYellow ?
Colors.Red : Colors.LightGoldenrodYellow;
Trace.WriteLine("HitTestCallback: drw.Brush = " + drw.Brush.ToString());
Trace.WriteLine("HitTestCallback: drw.IsFrozen = " + drw.IsFrozen.ToString());
Trace.WriteLine("HitTestCallback: drw.Brush.IsFrozen = " + drw.Brush.IsFrozen.ToString());
}
}
}
为了记录,我引用了构造 DrawingVisual
的代码并放入 VisualHostClass
PathGeometry pgnGeom = RenderPolygonWithHoles2Geometry(pgn);
DrawingVisual dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{
SolidColorBrush brush1 = new SolidColorBrush(Colors.LightGoldenrodYellow);
dc.DrawGeometry(brush1, null, pgnGeom);
}
myVisualHost.AddVisual(dv);
看来 dc.DrawGeometry(...)
创建的绘图已冻结,即不可修改。
传递我自己的绘图对我有用:
using (var dc = dv.RenderOpen())
{
dc.DrawDrawing(new GeometryDrawing(Brushes.LightGoldenrodYellow, null, pgnGeom));
}