質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

3回答

3395閲覧

WPF Canvasに描いた線だけを消す方法が分かりません。

gucha

総合スコア55

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

1クリップ

投稿2018/05/01 09:22

キャンバスに等間隔に線を引きグリッドの様に背景に表示させておこうとしています。
キャンバスサイズも変更させたいのでサイズを変更する時にグリッドを再描画させています。
しかし再描画する際に線だけを消す方法が分からず線以外の子要素も消えてしまいます。

MainWindow.xaml

C#

1 <Grid> 2 <ScrollViewer HorizontalAlignment="Stretch" HorizontalScrollBarVisibility="Auto" 3 VerticalScrollBarVisibility="Auto" VerticalAlignment="Stretch" Margin="0,0,0,235"> 4 <Canvas Name="gridCanvas" Background="#FF444444" Width="500" Height="70" SnapsToDevicePixels="True" HorizontalAlignment="Left" Margin="0,0,0,249"> 5 <Thumb Canvas.Top ="5" Canvas.Left="5" Width="30" Height="30" Name="thmub" /> 6 <StackPanel Canvas.Top="5" Canvas.Left="40" Width="30" Height="30" Background="#FFE66262"/> 7 </Canvas> 8 </ScrollViewer> 9 <Slider Name="slider" HorizontalAlignment="Left" Margin="10,105,0,0" VerticalAlignment="Top" Width="490" ValueChanged="Slider_ValueChanged"/> 10 </Grid>

キャンバスには色付けしたThumbとStackPanelを配置してあります。
スライダーでキャンバスサイズを変更します。
イメージ説明

MainWindow.xaml.cs

C#

1 public partial class MainWindow : Window 2 { 3 public MainWindow() 4 { 5 InitializeComponent(); 6 CreateGridView(500); 7 } 8 9 //スライダー変更でキャンバスのサイズ変更 10 private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) 11 { 12 int width = 500 + (int)slider.Value * 5; 13 gridCanvas.Width = width; 14 //グリッドの再描画 15 CreateGridView(width); 16 } 17 18 //グリッドの描画 19 private void CreateGridView(int gw) 20 { 21 //線だけ消す方法が分かりません。 22 //ThumbやStackPanelも線の上に表示させたいです。 23 gridCanvas.Children.Clear(); 24 int GRID_SIZE_W = gw; //横上限 25 int GRID_SIZE_H = 70; //縦上限 26 int span_W = gw / 10; //横間隔 27 int span_H = 70 / 3; //縦間隔 28 29 //縦線 30 for (int i = 0; i < GRID_SIZE_W; i += span_W) 31 { 32 gridCanvas.Children.Add(new Line() 33 { 34 X1 = i, 35 Y1 = 0, 36 X2 = i, 37 Y2 = GRID_SIZE_H, 38 Stroke = Brushes.LightGray, 39 StrokeThickness = 2, 40 }); 41 } 42 43 //横線 44 for (int i = 0; i < GRID_SIZE_H; i += span_H) 45 { 46 gridCanvas.Children.Add(new Line() 47 { 48 X1 = 0, 49 Y1 = i, 50 X2 = GRID_SIZE_W, 51 Y2 = i, 52 Stroke = Brushes.LightGray, 53 StrokeThickness = 2, 54 }); 55 } 56 } 57 }

gridCanvas.Children.Clear();で前に描画されたグリッドを全て消しているのですが、その際に子要素も消えてしまいます。
これを線だけを消すようにしたいのですが方法が分からないので教えてください。
あとChildre.Clear()で消さない場合もThumbとStackPanelが線の後ろ側に表示されるのも解決したいです。
線だけを別のキャンバスに描くような方法はあるのでしょうか?

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

参考までに、等間隔の線の描画は XAML だけでも可能です。
ミソは TileMode です。

xml

1<Canvas> 2 <Canvas.Background> 3 <VisualBrush TileMode="Tile" 4 Viewport="0,0,50,50" 5 ViewportUnits="Absolute"> 6 <VisualBrush.Visual> 7 <Border BorderThickness="0,0,1,1" 8 BorderBrush="Black" 9 Width="50" 10 Height="50" /> 11 </VisualBrush.Visual> 12 </VisualBrush> 13 </Canvas.Background> 14</Canvas>

投稿2018/05/02 05:20

gaya-K

総合スコア449

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gucha

2018/05/02 05:57

こちらの方法も意図している動作を確認しました。 教えて頂きありがとうございます。 線に細かく細工をしないのであればこちらの方が手軽で良さそうです。
guest

0

これを線だけを消すようにしたいのですが方法が分からないので教えてください。

線(Line)だけを消す方法としては、gridCanvasChildrenプロパティがUIElementCollectionクラスなので、そのクラスメソッドであるRemoveRemoveAtを使うことで削除することができます。
UIElementCollection クラス

ですが、Lineのみを削除後、座標を再計算したLineを追加するとThumbStackPanelの位置関係が意図したものにしづらいので、全削除 --> 再計算したLineを追加 --> 元のThumbとStackPanelを追加 との流れの方が良いでしょう。そうすることでご要望のかたちにはなります。

以下は、そのように直してみたClearGridView2です。差し替えて試してみてください。

C#

1 private void ClearGridView2(int gw) 2 { 3 //線だけ消す方法が分かりません。 4 //ThumbやStackPanelも線の上に表示させたいです。 5 // gridCanvas.Children.Clear(); 6 7 int GRID_SIZE_W = gw; //横上限 8 int GRID_SIZE_H = 70; //縦上限 9 int span_W = gw / 10; //横間隔 10 int span_H = 70 / 3; //縦間隔 11 12 List<UIElement> keepElems = new List<UIElement>(); 13 foreach (UIElement elem in gridCanvas.Children) 14 { 15 // UIElementがLineかどうか判定 16 if (elem.GetType() == typeof(Line)) 17 { 18 ; // Line 19 } 20 else 21 { 22 // Line以外を保存(ThumbとStackPanel) 23 keepElems.Add(elem); 24 } 25 } 26 27 // いったん全部クリア 28 gridCanvas.Children.Clear(); 29 30 //縦線 31 for (int i = 0; i < GRID_SIZE_W; i += span_W) 32 { 33 gridCanvas.Children.Add(new Line() 34 { 35 X1 = i, 36 Y1 = 0, 37 X2 = i, 38 Y2 = GRID_SIZE_H, 39 Stroke = Brushes.LightGray, 40 StrokeThickness = 2, 41 }); 42 } 43 44 //横線 45 for (int i = 0; i < GRID_SIZE_H; i += span_H) 46 { 47 gridCanvas.Children.Add(new Line() 48 { 49 X1 = 0, 50 Y1 = i, 51 X2 = GRID_SIZE_W, 52 Y2 = i, 53 Stroke = Brushes.LightGray, 54 StrokeThickness = 2, 55 }); 56 } 57 58 // ThumbとStackPanelを追加 59 foreach (UIElement elem in keepElems) 60 { 61 gridCanvas.Children.Add(elem); 62 } 63 } 64 }

ご質問の直接の回答としては以上ですが、質問者さんが本当にやりたいことへの解法としては、この方法よりは先の回答者さんの「Canvasを2つ使う」方法に賛同します。

投稿2018/05/01 13:30

編集2018/05/01 13:33
dodox86

総合スコア9183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gucha

2018/05/01 13:45

新しいリストへ格納しておく方法があったのですね! ご指摘の通りCanvasを2つ使う方法を今回は採用させて頂きましたが、この方法も勉強になりました。 複数の方法を教えて頂きありがとうございました。
guest

0

ベストアンサー

追加したLINEを別のところで保持しておいて、それを消しに行くとか言う方法もあるけど、
Canvasを複数用意するのが簡単じゃないかな。

<ScrollViewer> <Canvas Name="gridCanvas"/> <Canvas Name="gridCanvas2"/> </ScrollViewer>

投稿2018/05/01 10:52

kiichi54321

総合スコア1984

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gucha

2018/05/01 11:09

xamlに記述したところ プロパティContentは1回しか設定できません。 とエラーが出ました・・・。
dodox86

2018/05/01 12:27

以下のように、ScrollViewerのContentひとつのCanvasにしてしまって、その中で2つ持たせれば良いです。 <ScrollViewer>  <Canvas Name”parentCanvas”> <Canvas Name="gridCanvas"/> <Canvas Name="gridCanvas2"/> </Canvas> </ScrollViewer>
gucha

2018/05/01 13:45

dodox86さん コードをxamlに書いた時点では同じように警告が出ていましたが無視して開始したところエラーは消えました。 動作も期待通りの結果が得られましたのでこちらをベストアンサーとさせて頂きます。 お二人ともありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問