MainWindowにPublicとして定義しているからか、
子ウィンドウではMyLeftなどの変数が反応しません。
当たり前のことかもしれませんが、
Publicとなっているのに他のWindowからの変数?を
受け取れないのが不思議でなりません。
nya-3さんご自身が書いたコードがほとんどないのでC#の理解度を測れないのですが、オブジェクトとかインスタンスは理解されていますでしょうか?
{Binding HogeHoge}
とすると、そのDataContext
のオブジェクトのプロパティにバインドします。
データ バインディングの概要 - WPF .NET | Microsoft Docs
通常はViewModel
クラスを作成しWindow.DataContext
に設定するのですが、回答では省略することもあります。
2つのウィンドウで共通のViewModel
インスタンスをDataContext
に設定すれば、「データ共有」することになります。
前回の回答は盛沢山すぎたので、直接関係ないところはばっさりカットします。
INotifyPropertyChanged
実装には下記を使用しました。
NuGet Gallery | CommunityToolkit.Mvvm 7.1.2
参考リンクがドラッグ移動のみなので、お手軽に下記を使用しました(リサイズまで考慮すると実用になりません)
NuGet Gallery | Microsoft.Xaml.Behaviors.Wpf 1.1.39
こちらも似たような構成なので参考になるかと(MouseDragElementBehavior
のリベンジ成功!)
【WPF】Dictonaryの値をコンボボックスに表示できない、クラスを参照したい
MainWindow
xml
1 < Window
2 x: Class = " Qjru5bj6b9xz7g1.MainWindow "
3 xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation "
4 xmlns: x = " http://schemas.microsoft.com/winfx/2006/xaml "
5 x: Name = " Root "
6 Title = " MainWindow "
7 Width = " 800 "
8 Height = " 450 " >
9 < DataGrid AutoGenerateColumns = " False " ItemsSource = " {Binding Items} " >
10 < DataGrid.Columns >
11 < DataGridTextColumn Binding = " {Binding Title} " Header = " タイトル " />
12 < DataGridTextColumn Binding = " {Binding Left} " Header = " Left " />
13 < DataGridTextColumn Binding = " {Binding Top} " Header = " Top " />
14 < DataGridTextColumn Binding = " {Binding Width} " Header = " Width " />
15 < DataGridTextColumn Binding = " {Binding Height} " Header = " Height " />
16 < DataGridTemplateColumn Header = " 追加 " >
17 < DataGridTemplateColumn.CellTemplate >
18 < DataTemplate >
19 <!-- 追加ボタンで一部コピーしたアイテムを追加します(コードビハインドでの例) -->
20 < Button Click = " Add_Click " Content = " + " />
21 </ DataTemplate >
22 </ DataGridTemplateColumn.CellTemplate >
23 </ DataGridTemplateColumn >
24 < DataGridTemplateColumn Header = " 削除 " >
25 < DataGridTemplateColumn.CellTemplate >
26 < DataTemplate >
27 <!-- 削除ボタンでアイテムを削除します(MVVMコマンドでの例) -->
28 < Button
29 Command = " {Binding DataContext.DelCommand, Source={x:Reference Root}} "
30 CommandParameter = " {Binding} "
31 Content = " - " />
32 </ DataTemplate >
33 </ DataGridTemplateColumn.CellTemplate >
34 </ DataGridTemplateColumn >
35 </ DataGrid.Columns >
36 </ DataGrid >
37 </ Window >
cs
1 using System . Windows ;
2 using System . Windows . Controls ;
3
4 namespace Qjru5bj6b9xz7g1
5 {
6 public partial class MainWindow : Window
7 {
8 private readonly ViewModel vm = new ViewModel ( ) ;
9
10
11 public MainWindow ( )
12 {
13 InitializeComponent ( ) ;
14
15 DataContext = vm ;
16 new ChildWindow { DataContext = vm , } . Show ( ) ;
17 }
18
19 private void Add_Click ( object sender , RoutedEventArgs e )
20 {
21 if ( ( ( Button ) sender ) . DataContext is Item item )
22 {
23 //クリックした行と部分的に同じものを、1つ下の行に挿入
24 var i = vm . Items . IndexOf ( item ) ;
25 vm . Items . Insert ( i + 1 , new Item { Title = item . Title , Source = item . Source , } ) ;
26 }
27 }
28 }
29 }
ChildWindow
xml
1 < Window
2 x: Class = " Qjru5bj6b9xz7g1.ChildWindow "
3 xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation "
4 xmlns: x = " http://schemas.microsoft.com/winfx/2006/xaml "
5 xmlns: Behaviors = " http://schemas.microsoft.com/xaml/behaviors "
6 x: Name = " Root "
7 Title = " ChildWindow "
8 Width = " 800 "
9 Height = " 450 " >
10 < ItemsControl Background = " White " ItemsSource = " {Binding Items} " >
11 < ItemsControl.ContextMenu >
12 < ContextMenu >
13 <!-- 何もないところの右クリックメニューで新規アイテムを追加します(コードビハインドでの例) -->
14 < MenuItem Click = " Add_Click " Header = " 追加 " />
15 </ ContextMenu >
16 </ ItemsControl.ContextMenu >
17 < ItemsControl.ItemsPanel >
18 < ItemsPanelTemplate >
19 < Canvas />
20 </ ItemsPanelTemplate >
21 </ ItemsControl.ItemsPanel >
22 < ItemsControl.ItemTemplate >
23 < DataTemplate >
24 < Grid >
25 < Grid.ContextMenu >
26 < ContextMenu >
27 <!-- アイテムの右クリックメニューでアイテムを削除します(MVVMコマンドでの例) -->
28 < MenuItem
29 Command = " {Binding DataContext.DelCommand, Source={x:Reference Root}} "
30 CommandParameter = " {Binding} "
31 Header = " 削除 " />
32 </ ContextMenu >
33 </ Grid.ContextMenu >
34 < StackPanel >
35 < StackPanel.RenderTransform >
36 < TranslateTransform X = " {Binding Left} " Y = " {Binding Top} " />
37 </ StackPanel.RenderTransform >
38 < Behaviors: Interaction.Behaviors >
39 < Behaviors: MouseDragElementBehavior X = " {Binding Left, Mode=TwoWay} " Y = " {Binding Top, Mode=TwoWay} " />
40 </ Behaviors: Interaction.Behaviors >
41 < Image
42 Width = " {Binding Width} "
43 Height = " {Binding Height} "
44 Source = " {Binding Source} "
45 Stretch = " Fill " />
46 < TextBlock HorizontalAlignment = " Center " Text = " {Binding Title} " />
47 </ StackPanel >
48 </ Grid >
49 </ DataTemplate >
50 </ ItemsControl.ItemTemplate >
51 </ ItemsControl >
52 </ Window >
cs
1 using System . Windows ;
2
3 namespace Qjru5bj6b9xz7g1
4 {
5 public partial class ChildWindow : Window
6 {
7 public ChildWindow ( ) => InitializeComponent ( ) ;
8
9 private void Add_Click ( object sender , RoutedEventArgs e )
10 {
11 // DataContextがViewModelのはずなのでキャストして使用する
12 ( ( ViewModel ) DataContext ) . Items . Add ( new Item ( ) ) ;
13 }
14 }
15 }
ViewModel
cs
1 using System . Collections . ObjectModel ;
2 using System . Windows ;
3 using System . Windows . Input ;
4 using CommunityToolkit . Mvvm . ComponentModel ;
5 using CommunityToolkit . Mvvm . Input ;
6
7 namespace Qjru5bj6b9xz7g1
8 {
9 public class ViewModel
10 {
11 public ObservableCollection < Item > Items { get ; } = new ObservableCollection < Item > ( ) ;
12 public ICommand DelCommand { get ; }
13
14 public ViewModel ( )
15 {
16 Items . Add ( new Item { Title = "TN8001" , Left = 0 , Top = 0 , Width = 200 , Source = "https://teratail-v2.storage.googleapis.com/uploads/avatars/u13/132786/KnkDDC5A_thumbnail.jpg" , } ) ;
17 Items . Add ( new Item { Title = "nya-3" , Source = "https://www.gravatar.com/avatar/4d48208fd97fc8a0d8d0765a11592aa5?d=identicon" , } ) ;
18
19 DelCommand = new RelayCommand < Item > ( Del ) ;
20 }
21
22 private void Del ( Item item )
23 {
24 // MVVM的にはよろしくないが...
25 var r = MessageBox . Show ( "削除します。いいですか?" , "" , MessageBoxButton . YesNo , MessageBoxImage . Information ) ;
26 if ( r == MessageBoxResult . Yes )
27 {
28 Items . Remove ( item ) ; // 当該アイテムを削除
29 }
30 }
31 }
32
33 public class Item : ObservableObject // INotifyPropertyChanged
34 {
35 public string Title { get => _Title ; set => SetProperty ( ref _Title , value ) ; }
36 private string _Title = "タイトル" ;
37
38 public string Source { get => _Source ; set => SetProperty ( ref _Source , value ) ; }
39 private string _Source ;
40
41 public int Left { get => _Left ; set => SetProperty ( ref _Left , value ) ; }
42 private int _Left = 100 ;
43
44 public int Top { get => _Top ; set => SetProperty ( ref _Top , value ) ; }
45 private int _Top = 100 ;
46
47 public int Width { get => _Width ; set => SetProperty ( ref _Width , value ) ; }
48 private int _Width = 100 ;
49
50 public int Height { get => _Height ; set => SetProperty ( ref _Height , value ) ; }
51 private int _Height = 100 ;
52 }
53 }
ただ、詳細の項目に入れる値としては
「10,20,50,30」などと必ずひとまとめにし、
この形式の文字列て保存したいと思ってます。
まあそういうことも可能ですが、入力しにくいだけではないですか?
↓こういうのでやりたいですね(個人的には数字を入力するだけでもだるいです^^;
IntegerUpDown · xceedsoftware/wpftoolkit Wiki
「ファイル保存時にそういう形式にしたい」ということならわかります。
最終的には、以下のようにThumbをドラッグで移動させたり
拡縮ができるようにしようとしています。
結構こういうことがしたいって人多いですね。
しかし「これが決定版」みたいな実装がなくて、皆さんそれぞれ頑張っているという印象です(ちゃんとやろうとするとかなり難しいです)
日本語で検索する場合は、「wpf ラバーバンド」がいいです。
英語で検索する場合は、「wpf resizing adorner」がいいです。
英語で「rubber band」は、範囲選択の四角の話です(日本人が勘違いしているのでしょうか?^^;
C# wpf InkCanvasで四角、丸を描写後に消しゴムで消したい
InkCanvas.Childrenに入れたコントロールが、(何もしなくても)移動・リサイズできちゃう
これで妥協できるなら一番楽そうな気はします。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/03/31 06:05
2022/04/01 10:27
2022/04/05 05:09
2022/04/07 10:32