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

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

ただいまの
回答率

87.91%

WPF、canvas上の子要素の消去方法

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 8,804

score 7

canvas上のクリックした場所に図形やフォントを配置するというプログラムを、WPFで作っています。言語はC#、開発環境はvisual studio 2012 for Desktopを使用しています。
子要素をクリックで選んで消去させたいのですが、どのようにすれば良いのか分からないため、教えて頂きたいです。

該当のソースコード

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        double x = 0;
        double y = 0;
        double x1 = 0;
        double x2 = 0;
        double y1 = 0;
        double y2 = 0;
        double x3 = 0;
        double y3 = 0;
        bool flag = true;
        bool flag1 = true;
        int counter = 0;

        public MainWindow()
        {
            InitializeComponent();
        }

        // 線描画モード
        private void button_Click(object sender, RoutedEventArgs e)
        {
            flag = false;
        }

        // マウスクリック位置(押したとき)取得
        private void Root_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (flag == false)
            {
                Point pos1 = e.GetPosition(Root);
                x1 = pos1.X;
                y1 = pos1.Y;
            }

            if (flag1 == false)
            {
                Point pos3 = e.GetPosition(Root);
                x3 = pos3.X;
                y3 = pos3.Y;

                textblock();
            }
        }

        // マウスクリック位置(離したとき)取得
        private void Root_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (flag == false)
            {
                Point pos2 = e.GetPosition(Root);
                x2 = pos2.X;
                y2 = pos2.Y;

                x = x2;
                y = y2;

                CreateLine();
            }
        }

        // 線描画
        public void CreateLine()
        {
            Line blackLine = new Line();
            blackLine.X1 = x1;
            blackLine.Y1 = y1;
            blackLine.X2 = x2;
            blackLine.Y2 = y2;

            SolidColorBrush blackBrush = new SolidColorBrush();
            blackBrush.Color = Colors.Black;

            blackLine.StrokeThickness = 1;
            blackLine.Stroke = blackBrush;

            canvas.Children.Add(blackLine);
        }

        // 文字描画モード
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            flag = true;
            flag1 = false;
        }

        // textboxをtextblockにバインド
        public void textblock()
        {
            TextBlock tblock = new TextBlock();
            tblock.Width = 23;

            tblock.MouseEnter += tblock_MouseEnter;
            tblock.MouseLeave += tblock_MouseLeave;

            tblock.SetValue(Canvas.TopProperty, y3);
            tblock.SetValue(Canvas.LeftProperty, x3);

            Binding bind = new Binding();
            bind.ElementName = "textBox1";
            bind.Path = new PropertyPath(TextBox.TextProperty);
            bind.Mode = BindingMode.OneTime;
            tblock.SetBinding(TextBlock.TextProperty, bind);
            canvas.Children.Add(tblock);

            counter++;
            flag1 = true;
        }

        private void tblock_MouseLeave(object sender, MouseEventArgs e)
        {
            TextBlock tb = sender as TextBlock;
            tb.Background = SystemColors.WindowBrush;
        }

        void tblock_MouseEnter(object sender, MouseEventArgs e)
        {
            TextBlock tb = sender as TextBlock;
            tb.Background = SystemColors.HighlightBrush;
        }
    }
}


xmal

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="0*"/>
            <ColumnDefinition Width="100px"/>
        </Grid.ColumnDefinitions>
        <Viewbox x:Name="View" Stretch="UniformToFill">
            <Border x:Name="Root" Background="Transparent" MouseDown="Root_MouseDown" MouseUp="Root_MouseUp" Width="300" Height="400">
                <Canvas x:Name="canvas"  Background="Transparent" />
            </Border>
        </Viewbox>
        <StackPanel Orientation="Vertical" Background="Gray" Grid.Column="2">
            <Button x:Name="button" Content="線" Click="button_Click"/>
            <TextBox x:Name="textBox1" HorizontalAlignment="Left" Width="100"/>
            <Button x:Name="button1" Height="24" Click="button1_Click" VerticalAlignment="Top" HorizontalAlignment="Left" Content="文字" Width="100"/>
        </StackPanel>
    </Grid>
</Window>

上記のソースでは、ボタンクリックで追加する子要素を選択し、canvasをクリックして貼り付けることまでのみ可能です。
宜しくお願いします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

こんにちは。

どういうユーザビリティを想定されているかによってハンドルするイベントは異なると思います。
また、オブジェクトの種類に依らずに機能を実装できるように設計を最適化する必要はあると思いますが、
そこは本題ではないので触れません。

単純にオブジェクトを選択したタイミングでCanvasから削除すれば良いと思います。

public void CreateLine()
{
    Line blackLine = new Line();
    blackLine.MouseDown += (sender, e) =>
    {
        if (MessageBox.Show("消す?") == MessageBoxResult.OK)
        {
            canvas.Children.Remove(blackLine);
        }
    };
    blackLine.X1 = x1;
    blackLine.Y1 = y1;
    blackLine.X2 = x2;
    blackLine.Y2 = y2;

    SolidColorBrush blackBrush = new SolidColorBrush();
    blackBrush.Color = Colors.Black;

    blackLine.StrokeThickness = 1;
    blackLine.Stroke = blackBrush;

    canvas.Children.Add(blackLine);
}


※フラグの制御は割愛。

なお、もしこれがNGであればどういう実装だとどうNGなのか、先に要件を明確にするべきです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/08/28 07:32

    教えて頂いたコードを追記したところ考えていた通りの動作になりました。
    助かりました、ありがとうございます!

    キャンセル

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

  • ただいまの回答率 87.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る