実現したいこと
①サブウィンドウのDataGridに一覧を表示させる
②選択したDataGridの内容にあわせて、動作させる
(MainWindowsの画像を変更し、同じ画像の内容のものを表示させる)
③MainWindowにあるRectangleは、拡縮移動ができる
(Rectangle等を選択すると、選択した内容のDataGridが選択され、
DataGirdを選択すると、Rectangleにフォーカスがいく)
④SubWindowに「保存」ボタンがあり、それを押すとテキストファイルとして保存できる
①~③の動作イメージです。Excelを利用して作ってます。
黒い太枠が今選択しているもので、
薄い水色背景は同じ画像のものという意味です。
現在、Rectangle(Button)の表示、拡縮、移動機能は出来ました。
DataGridへのデータ表示もできました。
あとは、ButtonとDataGridの連動、
そしてDataGridで選択を変更した時に画像が違う場合に
画像背景とRectangleの変更の実装です。
前提
WPF 動的生成したRectangleがドラッグで移動できない、Bindingが難しい…
https://teratail.com/questions/j700zzpncph60k
→私には難しくて理解が出来ませんでした。申し訳ありません。
リサイズハンドルをAdornerで実装する
https://como-2.hatenadiary.org/entry/20110428/1303996288
→これを元に、フォーカス後に移動とかも実装しました。
発生している問題・エラーメッセージ
MVVMもそうですが、データの流れが良く分かりません。
一人で作っているため、自分がデータの流れを読めれば良く
速度とかもそこまで気にしていないため、自分で理解できる作成方法が一番だと思いました。
MVVMとかBindingとかあまり理解できていないので色々と間違っているかもしれませんが、データの値が追いやすいものにして、上記②を実現させたいです。
ViewModelを作成し、MainWindowにもDataWindowにも
DataContextに入れる?ことにしました。
MainWindowで□ボタンを押したらDataGridにも追加されるところまでは出来ました。
該当のソースコード
MainWindow.xaml
1<Window x:Class="ImageMapCreate.MainWindow" 2 x:Name="Root" 3 mc:Ignorable="d" 4 Title="MainWindow" Height="630" Width="800"> 5 6 <Window.Resources> 7 <!--リサイズハンドル用のテンプレート定義--> 8 <ControlTemplate TargetType="Thumb" x:Key="ResizeHandleTemplate"> 9 <Ellipse Width="10" Height="10" Margin="-3" 10 Stroke="DimGray" Fill="LightSteelBlue"/> 11 </ControlTemplate> 12 <!--装飾用のテンプレート定義--> 13 <ControlTemplate x:Key="AdornerTemplate"> 14 <Grid> 15 <Thumb Name="MoveThumb" 16 HorizontalAlignment="Center" VerticalAlignment="Center" 17 Template="{StaticResource ResizeHandleTemplate}" 18 DragDelta="ResizeThumb_DragDelta"/> 19 <Thumb Name="ResizeThumb_LT" 20 HorizontalAlignment="Left" VerticalAlignment="Top" 21 Template="{StaticResource ResizeHandleTemplate}" 22 DragDelta="ResizeThumb_DragDelta"/> 23 <Thumb Name="ResizeThumb_RT" 24 HorizontalAlignment="Right" VerticalAlignment="Top" 25 Template="{StaticResource ResizeHandleTemplate}" 26 DragDelta="ResizeThumb_DragDelta"/> 27 <Thumb Name="ResizeThumb_LB" 28 HorizontalAlignment="Left" VerticalAlignment="Bottom" 29 Template="{StaticResource ResizeHandleTemplate}" 30 DragDelta="ResizeThumb_DragDelta"/> 31 <Thumb Name="ResizeThumb_RB" 32 HorizontalAlignment="Right" VerticalAlignment="Bottom" 33 Template="{StaticResource ResizeHandleTemplate}" 34 DragDelta="ResizeThumb_DragDelta"/> 35 </Grid> 36 </ControlTemplate> 37 38 </Window.Resources> 39 <Grid> 40 <StackPanel Orientation="Vertical"> 41 <ToolBar Height="30"> 42 <Button x:Name="Create_rect" Content="□" Click="Create_rect_Click"></Button> 43 </ToolBar> 44 45 <Canvas Name="MyCanvas"> 46 <Image Width="800" Height="600"/> 47 <Button x:Name="ButtonStyleTemp" 48 Width="{Binding Width}" 49 Height="{Binding Height}" 50 Canvas.Left="{Binding X}" 51 Canvas.Top="{Binding Y}" 52 Content="{Binding HintText}" 53 Visibility="Hidden"> 54 <Button.Style> 55 <Style TargetType="Button"> 56 <Style.Triggers> 57 <Trigger Property="IsFocused" Value="True"> 58 <Setter Property="local:AdornedBy.Template" 59 Value="{StaticResource AdornerTemplate}"/> 60 </Trigger> 61 </Style.Triggers> 62 </Style> 63 </Button.Style> 64 </Button> 65 </Canvas > 66 67 </StackPanel> 68 </Grid>
MainWindow.cs
1public partial class MainWindow : Window 2 { 3 private readonly ViewModel vm = new ViewModel(); 4 public MainWindow() 5 { 6 InitializeComponent(); 7 8 DataContext = vm; 9 var window = new DataWindow(); 10 window.DataContext = vm; 11 window.Show(); 12 } 13 14 private void Create_rect_Click(object sender, RoutedEventArgs e) 15 { 16<!--省略--> 17 } 18 19 private void ResizeThumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e) 20 { 21 var thumb = sender as Thumb; 22 if (thumb == null) return; 23 var adored = AdornedBy.GetAdornedElementFromTemplateChild(thumb) as FrameworkElement; 24 if (adored == null) return; 25 Debug.WriteLine(adored.Name); 26 27 if (thumb.Name == "MoveThumb") 28 { 29 Canvas.SetLeft(adored, Canvas.GetLeft(adored) + e.HorizontalChange); 30 Canvas.SetTop(adored, Canvas.GetTop(adored) + e.VerticalChange); 31 e.Handled = true; 32 return; 33 } 34 var befo_bottom = Canvas.GetBottom(adored); 35 var befo_right = Canvas.GetRight(adored); 36 var befo_top = Canvas.GetTop(adored); 37 var befo_left = Canvas.GetLeft(adored); 38 var after_left = 0; 39 var after_top = 0; 40 var after_right = 0; 41 var after_bottom = 0; 42 var after_width = 0; 43 var after_height = 0; 44 //移動ではない場合 45 46 if (thumb.Name == "ResizeThumb_LT") 47 { 48 after_left = (int)(Canvas.GetLeft(adored) + e.HorizontalChange); 49 after_top = (int)(Canvas.GetTop(adored) + e.VerticalChange); 50 after_width = (int)(adored.Width - e.HorizontalChange); 51 after_height= (int)(adored.Height - e.VerticalChange); 52 after_right = after_left + after_width; 53 after_bottom = after_top + after_height; 54 if (after_width < 20) return; 55 if (after_height < 20) return; 56 if (after_left > after_right) return; 57 if (after_top > after_bottom) return; 58 adored.Height = after_height; 59 Canvas.SetTop(adored, after_top); 60 adored.Width = after_width; 61 Canvas.SetLeft(adored, after_left); 62 } 63 64 if (thumb.Name == "ResizeThumb_RT") 65 { 66 after_left = (int)(Canvas.GetLeft(adored));//LEFTは変わらない 67 after_top = (int)(Canvas.GetTop(adored) + e.VerticalChange); 68 after_width = (int)(adored.Width + e.HorizontalChange); 69 after_height = (int)(adored.Height - e.VerticalChange); 70 after_right = after_left + after_width; 71 after_bottom = after_top + after_height; 72 if (after_width < 20) return; 73 if (after_height < 20) return; 74 if (after_left > after_right) return; 75 if (after_top > after_bottom) return; 76 adored.Height = after_height; 77 Canvas.SetTop(adored, after_top); 78 adored.Width = after_width; 79 Canvas.SetLeft(adored, after_left); 80 } 81 82 if (thumb.Name == "ResizeThumb_LB") 83 { 84 after_left = (int)(Canvas.GetLeft(adored) + e.HorizontalChange); 85 after_top = (int)(Canvas.GetTop(adored));//TOPは変わらない 86 after_width = (int)(adored.Width - e.HorizontalChange); 87 after_height = (int)(adored.Height + e.VerticalChange); 88 after_right = after_left + after_width; 89 after_bottom = after_top + after_height; 90 if (after_width < 20) return; 91 if (after_height < 20) return; 92 if (after_left > after_right) return; 93 if (after_top > after_bottom) return; 94 adored.Height = after_height; 95 Canvas.SetTop(adored, after_top); 96 adored.Width = after_width; 97 Canvas.SetLeft(adored, after_left); 98 } 99 if (thumb.Name == "ResizeThumb_RB") 100 { 101 after_left = (int)(Canvas.GetLeft(adored));//LEFTは変わらない 102 after_top = (int)(Canvas.GetTop(adored));//Topも変わらない 103 after_width = (int)(adored.Width + e.HorizontalChange); 104 after_height = (int)(adored.Height + e.VerticalChange); 105 after_right = after_left + after_width; 106 after_bottom = after_top + after_height; 107 if (after_width < 20) return; 108 if (after_height < 20) return; 109 if (after_left > after_right) return; 110 if (after_top > after_bottom) return; 111 adored.Height = after_height; 112 Canvas.SetTop(adored, after_top); 113 adored.Width = after_width; 114 Canvas.SetLeft(adored, after_left); 115 } 116 } 117 118 } 119
DataWindow.xaml
1 <DockPanel> 2 <ToolBar Height="30" DockPanel.Dock="Top" FontWeight="Bold" > 3 <Button x:Name="ReadFileB" Content="ファイル読み込み" Click="ReadFile_Click" Background="#FFFFBCDE" /> 4 <Button x:Name="WriteFileB" Content="ファイル書き込み" Click="WriteFile_Click" Background="#FFAFFFD5" /> 5 <Button x:Name="AddB" Content="追加" Click="Add_Click"/> 6 </ToolBar> 7 <!--<rg:ReoGridControl x:Name = "ReoGrid" Height="300" />--> 8 <DataGrid x:Name="MyGrid" ItemsSource="{Binding Items, UpdateSourceTrigger=PropertyChanged}" CanUserSortColumns="False" SelectionChanged="DataGrid_SelectionChanged" AutoGenerateColumns="False" CanUserReorderColumns="False" CanUserAddRows="False" > 9 <DataGrid.Columns> 10 <DataGridTextColumn Header="番号" Binding="{Binding Num}" IsReadOnly="True" /> 11 <DataGridTextColumn Header="タイトル" Binding="{Binding Title}" /> 12 <DataGridTextColumn Header="画像ファイル名" Binding="{Binding PicName}" IsReadOnly="True" /> 13 <DataGridTextColumn Header="X" Binding="{Binding X" /> 14 <DataGridTextColumn Header="Y" Binding="{Binding Y}" /> 15 <DataGridTextColumn Header="W" Binding="{Binding Width}" /> 16 <DataGridTextColumn Header="H" Binding="{Binding Height}" /> 17 <DataGridTextColumn Header="ヒント" Binding="{Binding HintText}" /> 18 <DataGridTextColumn Header="線の色" Binding="{Binding BordColor}" /> 19 <DataGridTextColumn Header="塗り色" Binding="{Binding FillColor}" /> 20 <DataGridTextColumn Header="次リンク" Binding="{Binding NextLink}" IsReadOnly="True"/> 21 <DataGridTemplateColumn Header="追加" x:Name="Add"> 22 <DataGridTemplateColumn.CellTemplate> 23 <DataTemplate> 24 <Button Click="Add_Click" Content="+" /> 25 </DataTemplate> 26 </DataGridTemplateColumn.CellTemplate> 27 </DataGridTemplateColumn> 28 <DataGridTemplateColumn Header="削除" x:Name="Del"> 29 <DataGridTemplateColumn.CellTemplate> 30 <DataTemplate> 31 <Button Click="Del_Click" Content="-" /> 32 </DataTemplate> 33 </DataGridTemplateColumn.CellTemplate> 34 </DataGridTemplateColumn> 35 </DataGrid.Columns> 36 </DataGrid> 37 </DockPanel>
DataWindow.xaml.cs
1 private void Add_Click(object sender, RoutedEventArgs e) 2 { 3 ViewModel.Items.Add(new Item{ Num = 1, Title ="タイトル"});//とりあえず 4 } 5 6 private void Del_Click(object sender, RoutedEventArgs e) 7 { 8 var dataGrid = sender as DataGrid; 9 var cellInfos = MyGrid.SelectedCells; 10 if (cellInfos.Count == 0) 11 { 12 return; 13 } 14 var cellInfo = cellInfos[0]; 15 var item = cellInfo.Item; 16 var rowIndex = MyGrid.Items.IndexOf(item); 17 ViewModel.Items.RemoveAt(rowIndex); 18 19 }
試したこと
adoredという所で、「Name」と指定すれば情報が取得できたので、
今動かしているものの情報は取れそうな気がします。
それをどうやってDataGridに連動させるかが良く分かりません。
回答、アドバイスのほど、よろしくお願いいたします。
補足情報(FW/ツールのバージョンなど)
WPF C#
.NET 6.0
CommunityToolkit.Mvvm 8.2.1
