このような透明なキャンバスでさえ、背景を再描画する必要があります(背後にあるものも含まれます)。おそらくこれにはいくつかのハックがありますが、コンポーネントのちらつきの問題に遭遇するたびに、コンポーネント(またはカスタム)のダブルバッファリングを活用するなど、本当に満足のいく解決策はありませんでした。このようなライブグラフィックインタラクションがアプリケーションの必要な部分になるとき、私は常に、グラフィックを「正しい方法」で実行するものに移動することが最善の選択肢であることに気づきました。WPF、XNA、またはDirectXは、おそらくこの問題に対する最良の答えです。WPFは、この種の1つのイベント->多くのコンポーネントのパラダイムをコーディングするのをはるかに簡単にするルーティングされたイベントのようなものも追加します。
これは、winformsアプリケーションでWPF相互運用性コンポーネントを使用する例です。
1)フォームに新しいElementHostを追加します(elementHost1
ここではこれを呼び出しました)
2)プロジェクトに新しいWPF UserControlを追加します(私はそれを呼び出しましたTreeCanvas
)
XAML
<UserControl x:Class="WindowsFormsApplication1.TreeCanvas"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="300" Height="300">
<Grid>
<Canvas Name="Canvas1">
<TreeView Canvas.Left="0" Canvas.Top="0" Height="300" Name="TreeView1" Width="300" />
</Canvas>
</Grid>
TreeCanvasのコードビハインドには何も必要ありません。生成されたコードはInitializeComponent();
、今のところ必要なものだけです。
そしてあなたのフォームコード
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
using System.Windows.Media;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
//make a new TreeCanvas
private TreeCanvas MyTreeCanvas = new TreeCanvas();
public Form1()
{
InitializeComponent();
//attach the TreeCanvas component to the element host
this.Width = 400;
this.Height = 400;
elementHost1.Child = MyTreeCanvas;
elementHost1.Location = new System.Drawing.Point(30, 30);
elementHost1.Height = 300;
elementHost1.Width = 300;
// Just adding some random stuff to the treeview
int i = 0;
int j = 0;
for (i = 0; i <= 10; i++)
{
TreeViewItem nitm = new TreeViewItem();
nitm.Header = "Item " + Convert.ToString(i);
MyTreeCanvas.TreeView1.Items.Add(nitm);
for (j = 1; j <= 3; j++)
{
TreeViewItem itm = (TreeViewItem)MyTreeCanvas.TreeView1.Items[i];
itm.Items.Add("Item " + Convert.ToString(j));
}
}
//Draw a line on the canvas with the treeview
Line myLine = new Line();
myLine.Stroke = System.Windows.Media.Brushes.Red;
myLine.X1 = 1;
myLine.X2 = 50;
myLine.Y1 = 1;
myLine.Y2 = 300;
myLine.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
myLine.VerticalAlignment = VerticalAlignment.Center;
myLine.StrokeThickness = 2;
MyTreeCanvas.Canvas1.Children.Add(myLine);
}
}
}
これにより、キャンバス内のツリービューが表示され、その上にペイントして、下のツリービューをクリックして操作することができます(マウスのスクロールイベントなどを含む)。
行を直接クリックした場合、クリックは通過しません。同様に、マウスがキャンバス上の行を直接ホバリングしている場合、スクロールイベントなどは通過しませんが、ルーティングされたイベントを読み取ると、非常に簡単に配線できます。 TreeCanvasクラス内から一緒にそれらを。