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

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

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

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

WPF

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

Q&A

解決済

1回答

898閲覧

XAMLをC#で記述して、Imageの切り替え、イベントを追加したい。

chiken

総合スコア14

C#

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

WPF

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

2グッド

1クリップ

投稿2022/10/11 08:22

実現したいこと

XAMLをC#で記述して下記を作っています。
①ボタンを押すごとにImageが1つの画面、2つの画面と切り替えられる。
(お試しなので1つ目の画面のみImageを追加)
②Imageの1つ目はマウスホイールによる挙動等のイベントを追加したい。

発生している問題・エラーメッセージ

①下記のソースコードでは、ボタンを押すごとにRowが追加されていってしまいます。
②マウスホイール関数のGetPositionにあるScrollViewer.Nameの設定方法がわかりません。

該当のソースコード

XAML

1<Window x:Class="WpfApp1.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:WpfApp1" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="450" Width="800"> 9 10 <Grid> 11 <Grid ShowGridLines="True"> 12 <Grid.RowDefinitions> 13 <RowDefinition Height="*"/> 14 <RowDefinition Height="10*"/> 15 <RowDefinition Height="*"/> 16 </Grid.RowDefinitions> 17 <Grid.ColumnDefinitions> 18 <ColumnDefinition Width="*"/> 19 <ColumnDefinition Width="10*"/> 20 <ColumnDefinition Width="*"/> 21 </Grid.ColumnDefinitions> 22 <Grid Name="grid1" Grid.Row="1" Grid.Column="1" /> 23 24 <StackPanel Grid.Row="1" Grid.Column="2"> 25 <Button Click="Button_Click">test1</Button> 26 </StackPanel> 27 </Grid> 28 </Grid> 29</Window>

C#

1using System.Windows; 2using System.Windows.Controls; 3using System.Windows.Input; 4using System.Windows.Media; 5using System.Windows.Media.Imaging; 6using System.IO; 7 8namespace WpfApp1 9{ 10 /// <summary> 11 /// MainWindow.xaml の相互作用ロジック 12 /// </summary> 13 public partial class MainWindow : Window 14 { 15 BitmapImage _bmpImage1; 16 System.Windows.Controls.Image _image1; 17 18 public MainWindow() 19 { 20 InitializeComponent(); 21 22 BitmapImage bmpImage = new BitmapImage(); 23 using (FileStream stream = File.OpenRead(@"./image1.png")) 24 { 25 bmpImage.BeginInit(); 26 bmpImage.StreamSource = stream; 27 bmpImage.DecodePixelWidth = 500; 28 bmpImage.CacheOption = BitmapCacheOption.OnLoad; 29 bmpImage.CreateOptions = BitmapCreateOptions.None; 30 bmpImage.EndInit(); 31 bmpImage.Freeze(); 32 } 33 34 _bmpImage1 = bmpImage; 35 36 } 37 38 private bool flg = true; 39 private void Button_Click(object sender, RoutedEventArgs e) 40 { 41 /* 42 * ここでgrid1にある内容をクリアできればいい? 43 */ 44 45 CreateImageViewer(flg); 46 47 flg = !flg; 48 } 49 50 private void CreateImageViewer(bool flg) 51 { 52 if (flg) 53 { 54 grid1.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(15.0d) }); 55 grid1.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1.0, GridUnitType.Star) }); 56 57 Border border1 = new Border(); 58 Thickness marginThickness1 = new Thickness(5, 0, 5, 0); 59 border1.Margin = marginThickness1; 60 border1.Background = System.Windows.Media.Brushes.Gray; 61 Grid.SetRow(border1, 0); 62 63 TextBlock txt1 = new TextBlock(); 64 txt1.Foreground = System.Windows.Media.Brushes.Black; 65 txt1.HorizontalAlignment = System.Windows.HorizontalAlignment.Center; 66 txt1.VerticalAlignment = VerticalAlignment.Center; 67 txt1.Text = "image1"; 68 69 border1.Child = txt1; 70 71 Border border2 = new Border(); 72 Grid.SetRow(border2, 1); 73 Thickness marginThickness2 = new Thickness(5, 0, 5, 5); 74 border2.Margin = marginThickness2; 75 border2.Background = System.Windows.Media.Brushes.Silver; 76 77 ScrollViewer scrollViewer = new ScrollViewer(); 78 scrollViewer.Name = "ScrollViewer1"; 79 scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden; 80 scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden; 81 scrollViewer.PreviewMouseWheel += new MouseWheelEventHandler(ScrollViewer_PreviewMouseWheel); 82 83 _image1 = new System.Windows.Controls.Image(); 84 _image1.Name = "image1"; 85 _image1.Source = _bmpImage1; 86 border2.Child = _image1; 87 88 grid1.Children.Add(border1); 89 grid1.Children.Add(border2); 90 } 91 else 92 { 93 grid1.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1.0, GridUnitType.Star) }); 94 grid1.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1.0, GridUnitType.Star) }); 95 96 // 上半分 97 Grid grid2 = new Grid(); 98 grid2.ShowGridLines = true; 99 100 grid2.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(15.0d) }); 101 grid2.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1.0, GridUnitType.Star) }); 102 103 Border border1 = new Border(); 104 Thickness marginThickness1 = new Thickness(5, 0, 5, 0); 105 border1.Margin = marginThickness1; 106 border1.Background = System.Windows.Media.Brushes.Gray; 107 Grid.SetRow(border1, 0); 108 109 TextBlock txt1 = new TextBlock(); 110 txt1.Foreground = System.Windows.Media.Brushes.Black; 111 txt1.HorizontalAlignment = System.Windows.HorizontalAlignment.Center; 112 txt1.VerticalAlignment = VerticalAlignment.Center; 113 txt1.Text = "image2"; 114 115 border1.Child = txt1; 116 117 Border border2 = new Border(); 118 Grid.SetRow(border2, 1); 119 Thickness marginThickness2 = new Thickness(5, 0, 5, 5); 120 border2.Margin = marginThickness2; 121 border2.Background = System.Windows.Media.Brushes.Silver; 122 123 124 grid2.Children.Add(border1); 125 grid2.Children.Add(border2); 126 127 grid1.Children.Add(grid2); 128 129 // 下半分 130 Grid grid3 = new Grid(); 131 132 Grid.SetRow(grid3, 1); 133 grid3.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(15.0d) }); 134 grid3.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1.0, GridUnitType.Star) }); 135 136 Border border3 = new Border(); 137 Thickness marginThickness3 = new Thickness(5, 0, 5, 0); 138 border3.Margin = marginThickness3; 139 border3.Background = System.Windows.Media.Brushes.Gray; 140 Grid.SetRow(border3, 0); 141 142 TextBlock txt2 = new TextBlock(); 143 txt2.Foreground = System.Windows.Media.Brushes.Black; 144 txt2.HorizontalAlignment = System.Windows.HorizontalAlignment.Center; 145 txt2.VerticalAlignment = VerticalAlignment.Center; 146 txt2.Text = "image3"; 147 148 border3.Child = txt2; 149 150 Border border4 = new Border(); 151 Thickness marginThickness4 = new Thickness(5, 0, 5, 5); 152 border4.Margin = marginThickness4; 153 border4.Background = System.Windows.Media.Brushes.Silver; 154 155 Grid.SetRow(border4, 1); 156 157 grid3.Children.Add(border3); 158 grid3.Children.Add(border4); 159 160 grid1.Children.Add(grid3); 161 } 162 } 163 164 // マウスを押下した点を保存 165 System.Windows.Point _MouseDownStartPoint = new System.Windows.Point(0, 0); 166 // マウスの現在地 167 System.Windows.Point _MouseCurrentPoint = new System.Windows.Point(0, 0); 168 //画像倍率 169 double _dispScale = 1; 170 171 private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e) 172 { 173 //キャストではできないから他の方法を探すが見つけられません 174 _MouseCurrentPoint = e.GetPosition((IInputElement)"ScrollViewer1"); 175 176 var scale = 1.0; 177 178 if (e.Delta > 0) scale = 1.25; 179 else scale = 1 / 1.25; 180 181 var matrix = _image1.RenderTransform.Value; 182 183 matrix.ScaleAt(scale, scale, _MouseCurrentPoint.X, _MouseCurrentPoint.Y); 184 _image1.RenderTransform = new MatrixTransform(matrix); 185 186 _dispScale = _dispScale * scale; 187 } 188 } 189} 190

試したこと

上記の通りとなります。
①ではGridのクリアに類するものを探してみましたが見つけられませんでした。
②GetPositionの引数をどうすればよいかわかっていません。String→IInputElementのキャスト方法を調べましたがわかりませんでした。

何か解決策を教えていただければ幸いです。

補足情報(FW/ツールのバージョンなど)

VisualStudio2017
.Net Framework 4.8

TN8001👍を押しています
takezoux2😍を押しています

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

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

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

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

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

Zuishin

2022/10/11 11:17

ユーザーコントロールを使えばいいのでは?
guest

回答1

0

ベストアンサー

①下記のソースコードでは、ボタンを押すごとにRowが追加されていってしまいます。
*ここでgrid1にある内容をクリアできればいい?

単純にはgrid1の中身と、RowDefinitionsをクリアします(ただしイベント解除しないとリークします)
Panel.Children プロパティ (System.Windows.Controls) | Microsoft Learn
Grid.RowDefinitions プロパティ (System.Windows.Controls) | Microsoft Learn

②マウスホイール関数のGetPositionにあるScrollViewer.Nameの設定方法がわかりません。
//キャストではできないから他の方法を探すが見つけられません

ScrollViewerにイベントを付けたのですから、senderそれ自身です。

あるいはフィールド(メンバ変数)に取っておくとか、FindNameで探してくることもできます。
FrameworkElement.FindName(String) メソッド (System.Windows) | Microsoft Learn

cs

1using System.IO; 2using System.Windows; 3using System.Windows.Controls; 4using System.Windows.Input; 5using System.Windows.Media; 6using System.Windows.Media.Imaging; 7 8namespace Qd60jx9ak65tvo3 9{ 10 public partial class MainWindow : Window 11 { 12 private readonly BitmapImage _bmpImage1; 13 private Image _image1; 14 15 public MainWindow() 16 { 17 InitializeComponent(); 18 19 _bmpImage1 = new BitmapImage(); 20 using (var stream = File.OpenRead(@"./image1.png")) 21 { 22 _bmpImage1.BeginInit(); 23 _bmpImage1.StreamSource = stream; 24 _bmpImage1.DecodePixelWidth = 500; 25 _bmpImage1.CacheOption = BitmapCacheOption.OnLoad; 26 _bmpImage1.CreateOptions = BitmapCreateOptions.None; 27 _bmpImage1.EndInit(); 28 _bmpImage1.Freeze(); 29 } 30 } 31 32 private bool flg = true; 33 private void Button_Click(object sender, RoutedEventArgs e) 34 { 35 //ここでgrid1にある内容をクリアできればいい? 36 var scrollViewer = FindName("ScrollViewer1") as ScrollViewer; 37 if (scrollViewer != null) 38 { 39 // Window(のメソッド)でイベントをハンドリング(=WindowがscrollViewerを強参照) 40 // イベント解除しないとリーク(scrollViewerがGCされない) 41 scrollViewer.PreviewMouseWheel -= ScrollViewer_PreviewMouseWheel; 42 } 43 grid1.Children.Clear(); 44 grid1.RowDefinitions.Clear(); 45 46 CreateImageViewer(flg); 47 flg = !flg; 48 } 49 50 private void CreateImageViewer(bool flg) 51 { 52 if (flg) 53 { 54 grid1.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto }); 55 grid1.RowDefinitions.Add(new RowDefinition()); 56 57 var border1 = new Border 58 { 59 Margin = new Thickness(5, 0, 5, 0), 60 Background = Brushes.Gray, 61 Child = new TextBlock 62 { 63 HorizontalAlignment = HorizontalAlignment.Center, 64 Text = "image1", 65 }, 66 }; 67 Grid.SetRow(border1, 0); 68 grid1.Children.Add(border1); 69 70 71 var border2 = new Border 72 { 73 Margin = new Thickness(5, 0, 5, 5), 74 Background = Brushes.Silver, 75 }; 76 Grid.SetRow(border2, 1); 77 78 _image1 = new Image 79 { 80 Name = "image1", 81 Source = _bmpImage1, 82 }; 83 var scrollViewer = new ScrollViewer 84 { 85 Name = "ScrollViewer1", 86 VerticalScrollBarVisibility = ScrollBarVisibility.Disabled, 87 Content = _image1, 88 }; 89 scrollViewer.PreviewMouseWheel += ScrollViewer_PreviewMouseWheel; 90 border2.Child = scrollViewer; 91 grid1.Children.Add(border2); 92 } 93 else 94 { 95 grid1.RowDefinitions.Add(new RowDefinition()); 96 grid1.RowDefinitions.Add(new RowDefinition()); 97 98 // 上半分 99 var grid2 = new Grid 100 { 101 ShowGridLines = true, 102 }; 103 grid2.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto }); 104 grid2.RowDefinitions.Add(new RowDefinition()); 105 106 var border1 = new Border 107 { 108 Margin = new Thickness(5, 0, 5, 0), 109 Background = Brushes.Gray, 110 }; 111 Grid.SetRow(border1, 0); 112 113 var txt1 = new TextBlock 114 { 115 HorizontalAlignment = HorizontalAlignment.Center, 116 Text = "image2", 117 }; 118 border1.Child = txt1; 119 120 var border2 = new Border 121 { 122 Margin = new Thickness(5, 0, 5, 5), 123 Background = Brushes.Silver, 124 }; 125 Grid.SetRow(border2, 1); 126 127 128 grid2.Children.Add(border1); 129 grid2.Children.Add(border2); 130 131 grid1.Children.Add(grid2); 132 133 // 下半分 134 var grid3 = new Grid(); 135 Grid.SetRow(grid3, 1); 136 grid3.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto }); 137 grid3.RowDefinitions.Add(new RowDefinition()); 138 139 var border3 = new Border 140 { 141 Margin = new Thickness(5, 0, 5, 0), 142 Background = Brushes.Gray, 143 }; 144 Grid.SetRow(border3, 0); 145 146 var txt2 = new TextBlock 147 { 148 HorizontalAlignment = HorizontalAlignment.Center, 149 Text = "image3", 150 }; 151 border3.Child = txt2; 152 153 var border4 = new Border 154 { 155 Margin = new Thickness(5, 0, 5, 5), 156 Background = Brushes.Silver, 157 }; 158 Grid.SetRow(border4, 1); 159 160 grid3.Children.Add(border3); 161 grid3.Children.Add(border4); 162 163 grid1.Children.Add(grid3); 164 } 165 } 166 167 private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e) 168 { 169 //キャストではできないから他の方法を探すが見つけられません 170 var _MouseCurrentPoint = e.GetPosition((IInputElement)sender); 171 172 var scale = e.Delta > 0 ? 1.25 : 1 / 1.25; 173 var matrix = _image1.RenderTransform.Value; 174 175 matrix.ScaleAt(scale, scale, _MouseCurrentPoint.X, _MouseCurrentPoint.Y); 176 _image1.RenderTransform = new MatrixTransform(matrix); 177 } 178 } 179}

そもそもコードでView作るのって、めちゃくちゃ面倒じゃないですか?(わたしは途中で分からなくなりました^^;
例えばこんな感じにUserControlに分けられませんかね(DataTemplateとか手段はいろいろありますが)

MainWindow

xml

1<Window 2 x:Class="Qd60jx9ak65tvo3.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="800" 6 Height="450"> 7 <Grid> 8 <Grid ShowGridLines="True"> 9 <Grid.RowDefinitions> 10 <RowDefinition /> 11 <RowDefinition Height="10*" /> 12 <RowDefinition /> 13 </Grid.RowDefinitions> 14 <Grid.ColumnDefinitions> 15 <ColumnDefinition /> 16 <ColumnDefinition Width="10*" /> 17 <ColumnDefinition /> 18 </Grid.ColumnDefinitions> 19 <!-- ContentPresenterに特に意味はない GridでもBorderでもいい --> 20 <ContentPresenter 21 x:Name="cp" 22 Grid.Row="1" 23 Grid.Column="1" /> 24 <StackPanel Grid.Row="1" Grid.Column="2"> 25 <Button Click="Button_Click" Content="test1" /> 26 </StackPanel> 27 </Grid> 28 </Grid> 29</Window>

cs

1using System.IO; 2using System.Windows; 3using System.Windows.Media.Imaging; 4 5namespace Qd60jx9ak65tvo3 6{ 7 public partial class MainWindow : Window 8 { 9 private readonly BitmapImage _bmpImage1; 10 11 public MainWindow() 12 { 13 InitializeComponent(); 14 15 _bmpImage1 = new BitmapImage(); 16 using (var stream = File.OpenRead(@"./image1.png")) 17 { 18 _bmpImage1.BeginInit(); 19 _bmpImage1.StreamSource = stream; 20 _bmpImage1.DecodePixelWidth = 500; 21 _bmpImage1.CacheOption = BitmapCacheOption.OnLoad; 22 _bmpImage1.CreateOptions = BitmapCreateOptions.None; 23 _bmpImage1.EndInit(); 24 _bmpImage1.Freeze(); 25 } 26 } 27 28 private bool flg = true; 29 private void Button_Click(object sender, RoutedEventArgs e) 30 { 31 if (flg) 32 { 33 var view = new SingleView(); 34 view.image1.Source = _bmpImage1; 35 cp.Content = view; 36 } 37 else 38 { 39 var view = new SplitView(); 40 cp.Content = view; 41 } 42 43 flg = !flg; 44 } 45 } 46}

SingleView

xml

1<UserControl 2 x:Class="Qd60jx9ak65tvo3.SingleView" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 5 <Grid Margin="5"> 6 <Grid.RowDefinitions> 7 <RowDefinition Height="Auto" /> 8 <RowDefinition /> 9 </Grid.RowDefinitions> 10 <Border Background="Gray"> 11 <TextBlock HorizontalAlignment="Center" Text="image1" /> 12 </Border> 13 14 <Border Grid.Row="1" Background="Silver"> 15 <ScrollViewer PreviewMouseWheel="ScrollViewer_PreviewMouseWheel" VerticalScrollBarVisibility="Disabled"> 16 <Image x:Name="image1" /> 17 </ScrollViewer> 18 </Border> 19 </Grid> 20</UserControl>

cs

1using System.Windows; 2using System.Windows.Controls; 3using System.Windows.Input; 4using System.Windows.Media; 5 6namespace Qd60jx9ak65tvo3 7{ 8 public partial class SingleView : UserControl 9 { 10 public SingleView() => InitializeComponent(); 11 12 private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e) 13 { 14 var _MouseCurrentPoint = e.GetPosition((IInputElement)sender); 15 16 var scale = e.Delta > 0 ? 1.25 : 1 / 1.25; 17 var matrix = image1.RenderTransform.Value; 18 19 matrix.ScaleAt(scale, scale, _MouseCurrentPoint.X, _MouseCurrentPoint.Y); 20 image1.RenderTransform = new MatrixTransform(matrix); 21 22 } 23 } 24}

SplitView

xml

1<UserControl 2 x:Class="Qd60jx9ak65tvo3.SplitView" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 5 <Grid Margin="5"> 6 <Grid.RowDefinitions> 7 <RowDefinition /> 8 <RowDefinition /> 9 </Grid.RowDefinitions> 10 <Grid ShowGridLines="True"> 11 <Grid.RowDefinitions> 12 <RowDefinition Height="Auto" /> 13 <RowDefinition /> 14 </Grid.RowDefinitions> 15 <Border Background="Gray"> 16 <TextBlock HorizontalAlignment="Center" Text="image2" /> 17 </Border> 18 <Border Grid.Row="1" Background="Silver" /> 19 </Grid> 20 21 <Grid Grid.Row="1"> 22 <Grid.RowDefinitions> 23 <RowDefinition Height="Auto" /> 24 <RowDefinition /> 25 </Grid.RowDefinitions> 26 <Border Background="Gray"> 27 <TextBlock HorizontalAlignment="Center" Text="image3" /> 28 </Border> 29 <Border Grid.Row="1" Background="Silver" /> 30 </Grid> 31 </Grid> 32</UserControl>

cs

1using System.Windows.Controls; 2 3namespace Qd60jx9ak65tvo3 4{ 5 public partial class SplitView : UserControl 6 { 7 public SplitView() => InitializeComponent(); 8 } 9}

投稿2022/10/11 12:33

TN8001

総合スコア9321

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

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

chiken

2022/10/13 07:34

大変わかりやすい方法を提示していただきありがとうございます。 コードビハインドでの書き方も見やすく参考になりました。 UserControlで分けたほうが今後に活かせそうなので利用させていただきます。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問