teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

見直しキャンペーン中

2023/07/27 13:46

投稿

TN8001
TN8001

スコア10108

answer CHANGED
@@ -1,106 +1,106 @@
1
- > aaaの部分にはVMクラスのプロパティに紐づけたいのですがやり方がわからず困っています。
2
-
3
- 質問文は単純ですが2つの要素が合わさっています。
4
-
5
- 1つ目はビジュアルツリーの問題です。
6
-
7
- `DataGridColumn`はビジュアルツリーに含まれないため、素直には`ViewModel`にアクセスできません。
8
- [ツリー - WPF .NET Framework | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/desktop/wpf/advanced/trees-in-wpf)
9
-
10
- よくある手法は中継役(`BindingProxy`)を用意して、それ経由でアクセスします。
11
-
12
- `x:Reference`でコントロールを参照しても動きました。
13
- [c# - Binding datagrid column width - Stack Overflow](https://stackoverflow.com/questions/9313586/binding-datagrid-column-width)
14
-
15
- ---
16
-
17
- 2つ目は`DataGridLength`の問題です。
18
-
19
- `aaa`の型がわかりませんが、おそらく`double`等数値を想定されていると思います。
20
- `DataGridLength`は`Star`や`Auto`指定できるので、単なる数値ではありません
21
- [DataGridLength 構造体 (System.Windows.Controls) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.controls.datagridlength)
22
-
23
- `TwoWay`でバインドするには双方向のコンバータが必要です。
24
- [wpf - How do I databind a ColumnDefinition's Width or RowDefinition's Height? - Stack Overflow](https://stackoverflow.com/questions/147908/how-do-i-databind-a-columndefinitions-width-or-rowdefinitions-height)
25
-
26
- ```xaml
27
- <Window
28
- x:Class="Questions338171.MainWindow"
29
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
30
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
31
- xmlns:local="clr-namespace:Questions338171"
32
- Width="800"
33
- Height="450">
34
- <Window.DataContext>
35
- <local:ViewModel />
36
- </Window.DataContext>
37
- <Window.Resources>
38
- <local:BindingProxy x:Key="proxy" Data="{Binding}" />
39
- <local:DataGridLengthConverter x:Key="dataGridLengthConverter" />
40
- </Window.Resources>
41
- <DockPanel>
42
- <Slider
43
- x:Name="slider"
44
- DockPanel.Dock="Top"
45
- Maximum="{Binding ActualWidth, RelativeSource={RelativeSource self}}"
46
- Value="{Binding Width}" />
47
- <TextBlock DockPanel.Dock="Top" Text="{Binding Width}" />
48
- <DataGrid AutoGenerateColumns="False">
49
- <DataGrid.Columns>
50
- <DataGridTextColumn
51
- Width="{Binding Data.Width, Converter={StaticResource dataGridLengthConverter}, Mode=TwoWay, Source={StaticResource proxy}}"
52
- Binding="{Binding}"
53
- Header="BindingProxy" />
54
- <DataGridTextColumn
55
- Width="{Binding Value, Converter={StaticResource dataGridLengthConverter}, Mode=TwoWay, Source={x:Reference slider}}"
56
- Binding="{Binding}"
57
- Header="x:Reference" />
58
- </DataGrid.Columns>
59
- aaaa
60
- </DataGrid>
61
- </DockPanel>
62
- </Window>
63
- ```
64
-
65
- ```C#
66
- using CommunityToolkit.Mvvm.ComponentModel;
67
- using System;
68
- using System.Globalization;
69
- using System.Windows;
70
- using System.Windows.Controls;
71
- using System.Windows.Data;
72
-
73
- namespace Questions338171
74
- {
75
- class BindingProxy : Freezable
76
- {
77
- public object Data { get => GetValue(DataProperty); set => SetValue(DataProperty, value); }
78
- public static readonly DependencyProperty DataProperty
79
- = DependencyProperty.Register(nameof(Data), typeof(object), typeof(BindingProxy),
80
- new PropertyMetadata(null));
81
- protected override Freezable CreateInstanceCore() => new BindingProxy();
82
- }
83
-
84
- class DataGridLengthConverter : IValueConverter
85
- {
86
- public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
87
- => new DataGridLength((double)value);
88
- public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
89
- => ((DataGridLength)value).Value;
90
- }
91
-
92
- class ViewModel : ObservableObject
93
- {
94
- private double width = 150;
95
- public double Width { get => width; set => SetProperty(ref width, value); }
96
- }
97
-
98
- public partial class MainWindow : Window
99
- {
100
- public MainWindow() => InitializeComponent();
101
- }
102
- }
103
- ```
104
-
105
- こちらを使用しています。
1
+ > aaaの部分にはVMクラスのプロパティに紐づけたいのですがやり方がわからず困っています。
2
+
3
+ 質問文は単純ですが2つの要素が合わさっています。
4
+
5
+ 1つ目はビジュアルツリーの問題です。
6
+
7
+ `DataGridColumn`はビジュアルツリーに含まれないため、素直にはViewModelにアクセスできません。
8
+ [ツリー - WPF .NET Framework | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/desktop/wpf/advanced/trees-in-wpf)
9
+
10
+ よくある手法は中継役(`BindingProxy`)を用意して、それ経由でアクセスします。
11
+
12
+ `x:Reference`でコントロールを参照しても動きました。
13
+ [c# - Binding datagrid column width - Stack Overflow](https://stackoverflow.com/questions/9313586/binding-datagrid-column-width)
14
+
15
+ ---
16
+
17
+ 2つ目は`DataGridLength`の問題です。
18
+
19
+ `aaa`の型がわかりませんが、おそらく`double`等数値を想定されていると思います。
20
+ `DataGridLength`は`Star`や`Auto`指定できるので、単なる数値ではありません
21
+ [DataGridLength 構造体 (System.Windows.Controls) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.controls.datagridlength)
22
+
23
+ `TwoWay`でバインドするには双方向のコンバータが必要です。
24
+ [wpf - How do I databind a ColumnDefinition's Width or RowDefinition's Height? - Stack Overflow](https://stackoverflow.com/questions/147908/how-do-i-databind-a-columndefinitions-width-or-rowdefinitions-height)
25
+
26
+ ```xml
27
+ <Window
28
+ x:Class="Questions338171.MainWindow"
29
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
30
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
31
+ xmlns:local="clr-namespace:Questions338171"
32
+ Width="800"
33
+ Height="450">
34
+ <Window.DataContext>
35
+ <local:ViewModel />
36
+ </Window.DataContext>
37
+ <Window.Resources>
38
+ <local:BindingProxy x:Key="proxy" Data="{Binding}" />
39
+ <local:DataGridLengthConverter x:Key="dataGridLengthConverter" />
40
+ </Window.Resources>
41
+ <DockPanel>
42
+ <Slider
43
+ x:Name="slider"
44
+ DockPanel.Dock="Top"
45
+ Maximum="{Binding ActualWidth, RelativeSource={RelativeSource self}}"
46
+ Value="{Binding Width}" />
47
+ <TextBlock DockPanel.Dock="Top" Text="{Binding Width}" />
48
+ <DataGrid AutoGenerateColumns="False">
49
+ <DataGrid.Columns>
50
+ <DataGridTextColumn
51
+ Width="{Binding Data.Width, Converter={StaticResource dataGridLengthConverter}, Mode=TwoWay, Source={StaticResource proxy}}"
52
+ Binding="{Binding}"
53
+ Header="BindingProxy" />
54
+ <DataGridTextColumn
55
+ Width="{Binding Value, Converter={StaticResource dataGridLengthConverter}, Mode=TwoWay, Source={x:Reference slider}}"
56
+ Binding="{Binding}"
57
+ Header="x:Reference" />
58
+ </DataGrid.Columns>
59
+ aaaa
60
+ </DataGrid>
61
+ </DockPanel>
62
+ </Window>
63
+ ```
64
+
65
+ ```cs
66
+ using CommunityToolkit.Mvvm.ComponentModel;
67
+ using System;
68
+ using System.Globalization;
69
+ using System.Windows;
70
+ using System.Windows.Controls;
71
+ using System.Windows.Data;
72
+
73
+ namespace Questions338171
74
+ {
75
+ class BindingProxy : Freezable
76
+ {
77
+ public object Data { get => GetValue(DataProperty); set => SetValue(DataProperty, value); }
78
+ public static readonly DependencyProperty DataProperty
79
+ = DependencyProperty.Register(nameof(Data), typeof(object), typeof(BindingProxy),
80
+ new PropertyMetadata(null));
81
+ protected override Freezable CreateInstanceCore() => new BindingProxy();
82
+ }
83
+
84
+ class DataGridLengthConverter : IValueConverter
85
+ {
86
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
87
+ => new DataGridLength((double)value);
88
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
89
+ => ((DataGridLength)value).Value;
90
+ }
91
+
92
+ class ViewModel : ObservableObject
93
+ {
94
+ private double width = 150;
95
+ public double Width { get => width; set => SetProperty(ref width, value); }
96
+ }
97
+
98
+ public partial class MainWindow : Window
99
+ {
100
+ public MainWindow() => InitializeComponent();
101
+ }
102
+ }
103
+ ```
104
+
105
+ こちらを使用しています。
106
106
  [NuGet Gallery | CommunityToolkit.Mvvm 7.0.2](https://www.nuget.org/packages/CommunityToolkit.Mvvm/7.0.2)