回答編集履歴
1
見直しキャンペーン中
test
CHANGED
@@ -1,341 +1,171 @@
|
|
1
1
|
> PhotoShopの機能を模倣していくこと
|
2
|
+
|
3
|
+
入門者にはあまりに壮大な目標に感じますが、まあどこまでやるかによりますね。
|
4
|
+
|
5
|
+
PhotoShopは持っていませんが、ツールバーにある[TEXT]ボタンを選択して画面をクリックするとそこに枠が出る(ドラッグで範囲指定?)みたいなやつですね?
|
6
|
+
フォントや色を変更できて、欲を言えばマウスで移動やリサイズができる。と
|
7
|
+
|
8
|
+
|
9
|
+
凝ったUIの作りこみはロジック以上に難しいことが多いです(私はあまり手を出さないようにしています^^;
|
10
|
+
とはいえ出発点としてミニマムかつ、そこそこ遊べるような参考コードを書いてみました。
|
11
|
+
|
12
|
+
[仕様]
|
13
|
+
画像エリアをダブルクリックでその場所に`TextBox`を生成
|
14
|
+
`TextBox`の右クリックメニューに削除(コピー等は`TextBox`のコピーではなく、テキストのコピー)
|
15
|
+
テキストの編集はその場で可能(複数行に対応)
|
16
|
+
ほかのプロパティは`PropertyGrid`で編集(クリックした`TextBox`を`PropertyGrid`に割り当てるため、選択が少し重いです)
|
17
|
+
- 移動は`CanvasLeft`・`CanvasTop`
|
18
|
+
- サイズは`Width`・`Height`(`NaN`で自動調整)
|
19
|
+
- フォントはFontなんちゃら
|
20
|
+
- 色は`Foreground`
|
2
21
|
|
3
22
|
|
4
23
|
|
5
|
-
|
24
|
+
NuGetから`Extended.Wpf.Toolkit`をインストールしてください(`PropertyGrid`だけ使います)
|
6
25
|
|
7
|
-
|
8
|
-
|
9
|
-
PhotoShopは持っていませんが、ツールバーにある[TEXT]ボタンを選択して画面をクリックするとそこに枠が出る(ドラッグで範囲指定?)みたいなやつですね?
|
10
|
-
|
11
|
-
フォントや色を変更できて、欲を言えばマウスで移動やリサイズができる。と
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
凝ったUIの作りこみはロジック以上に難しいことが多いです(私はあまり手を出さないようにしています^^;
|
18
|
-
|
19
|
-
とはいえ出発点としてミニマムかつ、そこそこ遊べるような参考コードを書いてみました。
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
[仕様]
|
24
|
-
|
25
|
-
画像エリアをダブルクリックでその場所にTextBoxを生成
|
26
|
-
|
27
|
-
TextBoxの右クリックメニューに削除(コピー等はTextBoxのコピーではなく、テキストのコピー)
|
28
|
-
|
29
|
-
テキストの編集はその場で可能(複数行に対応)
|
30
|
-
|
31
|
-
ほかのプロパティはPropertyGridで編集(クリックしたTextBoxをPropertyGridに割り当てるため、選択が少し重いです)
|
32
|
-
|
33
|
-
- 移動はCanvasLeft CanvasTop
|
34
|
-
|
35
|
-
- サイズはWidth Height(NaNで自動調整)
|
36
|
-
|
37
|
-
- フォントはFontなんちゃら
|
38
|
-
|
39
|
-
- 色はForeground
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
NuGetから`Extended.Wpf.Toolkit`をインストールしてください(PropertyGridだけ使います)
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
```x
|
26
|
+
```xml
|
52
|
-
|
53
27
|
<Window
|
54
|
-
|
55
28
|
x:Class="Questions233943.MainWindow"
|
56
|
-
|
57
29
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
58
|
-
|
59
30
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
60
|
-
|
61
31
|
xmlns:local="clr-namespace:Questions233943"
|
62
|
-
|
63
32
|
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
64
|
-
|
65
33
|
Width="800"
|
66
|
-
|
67
34
|
Height="450">
|
68
|
-
|
69
35
|
<Window.Resources>
|
70
|
-
|
71
36
|
<ContextMenu x:Key="TextBoxContextMenu">
|
72
|
-
|
73
37
|
<MenuItem Command="ApplicationCommands.Copy" />
|
74
|
-
|
75
38
|
<MenuItem Command="ApplicationCommands.Cut" />
|
76
|
-
|
77
39
|
<MenuItem Command="ApplicationCommands.Paste" />
|
78
|
-
|
79
40
|
<MenuItem Click="DelMenuItem_Click" Header="削除" />
|
80
|
-
|
81
41
|
</ContextMenu>
|
82
42
|
|
83
|
-
|
84
|
-
|
85
43
|
<Style x:Key="TextBoxStyle" TargetType="{x:Type local:TextBoxEx}">
|
86
|
-
|
87
44
|
<Setter Property="AcceptsReturn" Value="True" />
|
88
|
-
|
89
45
|
<Setter Property="AcceptsTab" Value="True" />
|
90
|
-
|
91
46
|
<Setter Property="Background" Value="{x:Null}" />
|
92
|
-
|
93
47
|
<Setter Property="BorderBrush" Value="{x:Null}" />
|
94
|
-
|
95
48
|
<Setter Property="ContextMenu" Value="{StaticResource TextBoxContextMenu}" />
|
96
|
-
|
97
49
|
<Setter Property="FontSize" Value="16px" />
|
98
|
-
|
99
50
|
<Setter Property="FontWeight" Value="bold" />
|
100
|
-
|
101
51
|
<Setter Property="Foreground" Value="Red" />
|
102
|
-
|
103
52
|
<Setter Property="Text" Value="テキスト" />
|
104
|
-
|
105
53
|
<Setter Property="TextWrapping" Value="Wrap" />
|
106
|
-
|
107
54
|
<Setter Property="Template">
|
108
|
-
|
109
55
|
<Setter.Value>
|
110
|
-
|
111
56
|
<ControlTemplate TargetType="{x:Type TextBox}">
|
112
|
-
|
113
57
|
<Border
|
114
|
-
|
115
58
|
x:Name="border"
|
116
|
-
|
117
59
|
Background="{TemplateBinding Background}"
|
118
|
-
|
119
60
|
BorderBrush="{TemplateBinding BorderBrush}"
|
120
|
-
|
121
61
|
BorderThickness="{TemplateBinding BorderThickness}"
|
122
|
-
|
123
62
|
SnapsToDevicePixels="True">
|
124
|
-
|
125
63
|
<ScrollViewer
|
126
|
-
|
127
64
|
x:Name="PART_ContentHost"
|
128
|
-
|
129
65
|
Focusable="false"
|
130
|
-
|
131
66
|
HorizontalScrollBarVisibility="Hidden"
|
132
|
-
|
133
67
|
VerticalScrollBarVisibility="Hidden" />
|
134
|
-
|
135
68
|
</Border>
|
136
|
-
|
137
69
|
<ControlTemplate.Triggers>
|
138
|
-
|
139
70
|
<Trigger Property="IsMouseOver" Value="true">
|
140
|
-
|
141
71
|
<Setter TargetName="border" Property="BorderBrush" Value="#FF7EB4EA" />
|
142
|
-
|
143
72
|
</Trigger>
|
144
|
-
|
145
73
|
<Trigger Property="IsFocused" Value="true">
|
146
|
-
|
147
74
|
<Setter TargetName="border" Property="BorderBrush" Value="#FF7EB4EA" />
|
148
|
-
|
149
75
|
</Trigger>
|
150
|
-
|
151
76
|
</ControlTemplate.Triggers>
|
152
|
-
|
153
77
|
</ControlTemplate>
|
154
|
-
|
155
78
|
</Setter.Value>
|
156
|
-
|
157
79
|
</Setter>
|
158
|
-
|
159
80
|
</Style>
|
160
|
-
|
161
81
|
</Window.Resources>
|
162
|
-
|
163
82
|
<Grid>
|
164
|
-
|
165
83
|
<Grid.ColumnDefinitions>
|
166
|
-
|
167
84
|
<ColumnDefinition Width="2*" />
|
168
|
-
|
169
85
|
<ColumnDefinition Width="5" />
|
170
|
-
|
171
86
|
<ColumnDefinition />
|
172
|
-
|
173
87
|
</Grid.ColumnDefinitions>
|
174
|
-
|
175
88
|
<Canvas x:Name="canvas" MouseLeftButtonDown="Canvas_MouseLeftButtonDown">
|
176
|
-
|
177
89
|
<Image Source="Resources\whippet.jpg" />
|
178
|
-
|
179
90
|
</Canvas>
|
180
|
-
|
181
91
|
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
|
182
|
-
|
183
92
|
<xctk:PropertyGrid x:Name="propertyGrid" Grid.Column="2" />
|
184
|
-
|
185
93
|
</Grid>
|
186
|
-
|
187
94
|
</Window>
|
188
|
-
|
189
95
|
```
|
190
96
|
|
191
|
-
|
192
|
-
|
193
|
-
```
|
97
|
+
```cs
|
194
|
-
|
195
98
|
using System.Windows;
|
196
|
-
|
197
99
|
using System.Windows.Controls;
|
198
|
-
|
199
100
|
using System.Windows.Input;
|
200
101
|
|
201
|
-
|
202
|
-
|
203
102
|
namespace Questions233943
|
204
|
-
|
205
103
|
{
|
206
|
-
|
207
104
|
// PropertyGridでいじれるようにCanvas.Left Canvas.Topをラップ
|
208
|
-
|
209
105
|
public class TextBoxEx : TextBox
|
210
|
-
|
211
106
|
{
|
212
|
-
|
213
107
|
public static readonly DependencyProperty CanvasLeftProperty
|
214
|
-
|
215
108
|
= DependencyProperty.Register(nameof(CanvasLeft), typeof(double), typeof(TextBoxEx),
|
216
|
-
|
217
109
|
new FrameworkPropertyMetadata(0d, new PropertyChangedCallback(OnCanvasLeftChanged)));
|
218
|
-
|
219
110
|
public double CanvasLeft { get => (double)GetValue(CanvasLeftProperty); set => SetValue(CanvasLeftProperty, value); }
|
220
|
-
|
221
111
|
private static void OnCanvasLeftChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
|
222
|
-
|
223
112
|
{
|
224
|
-
|
225
113
|
if(obj is TextBoxEx ctrl) Canvas.SetLeft(ctrl, ctrl.CanvasLeft);
|
226
|
-
|
227
114
|
}
|
228
115
|
|
116
|
+
public static readonly DependencyProperty CanvasTopProperty
|
117
|
+
= DependencyProperty.Register(nameof(CanvasTop), typeof(double), typeof(TextBoxEx),
|
118
|
+
new FrameworkPropertyMetadata(0d, new PropertyChangedCallback(OnCanvasTopChanged)));
|
119
|
+
public double CanvasTop { get => (double)GetValue(CanvasTopProperty); set => SetValue(CanvasTopProperty, value); }
|
120
|
+
private static void OnCanvasTopChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
|
121
|
+
{
|
122
|
+
if(obj is TextBoxEx ctrl) Canvas.SetTop(ctrl, ctrl.CanvasTop);
|
123
|
+
}
|
124
|
+
}
|
229
125
|
|
126
|
+
public partial class MainWindow : Window
|
127
|
+
{
|
128
|
+
public MainWindow() => InitializeComponent();
|
230
129
|
|
231
|
-
public static readonly DependencyProperty CanvasTopProperty
|
232
|
-
|
233
|
-
= DependencyProperty.Register(nameof(CanvasTop), typeof(double), typeof(TextBoxEx),
|
234
|
-
|
235
|
-
new FrameworkPropertyMetadata(0d, new PropertyChangedCallback(OnCanvasTopChanged)));
|
236
|
-
|
237
|
-
public double CanvasTop { get => (double)GetValue(CanvasTopProperty); set => SetValue(CanvasTopProperty, value); }
|
238
|
-
|
239
|
-
private
|
130
|
+
private void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
240
|
-
|
241
131
|
{
|
242
|
-
|
132
|
+
if(e.ClickCount == 2)
|
133
|
+
{
|
134
|
+
var textBox = new TextBoxEx
|
135
|
+
{
|
136
|
+
Style = FindResource("TextBoxStyle") as Style,
|
243
|
-
|
137
|
+
CanvasLeft = e.GetPosition(canvas).X,
|
244
|
-
|
138
|
+
CanvasTop = e.GetPosition(canvas).Y
|
139
|
+
};
|
140
|
+
textBox.GotFocus += TextBox_GotFocus;
|
141
|
+
canvas.Children.Add(textBox);
|
142
|
+
}
|
245
143
|
}
|
246
144
|
|
247
|
-
}
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
public partial class MainWindow : Window
|
252
|
-
|
253
|
-
{
|
254
|
-
|
255
|
-
public MainWindow() => InitializeComponent();
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
private void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
260
|
-
|
261
|
-
{
|
262
|
-
|
263
|
-
if(e.ClickCount == 2)
|
264
|
-
|
265
|
-
{
|
266
|
-
|
267
|
-
var textBox = new TextBoxEx
|
268
|
-
|
269
|
-
{
|
270
|
-
|
271
|
-
Style = FindResource("TextBoxStyle") as Style,
|
272
|
-
|
273
|
-
CanvasLeft = e.GetPosition(canvas).X,
|
274
|
-
|
275
|
-
CanvasTop = e.GetPosition(canvas).Y
|
276
|
-
|
277
|
-
};
|
278
|
-
|
279
|
-
textBox.GotFocus += TextBox_GotFocus;
|
280
|
-
|
281
|
-
canvas.Children.Add(textBox);
|
282
|
-
|
283
|
-
}
|
284
|
-
|
285
|
-
}
|
286
|
-
|
287
|
-
|
288
|
-
|
289
145
|
private void TextBox_GotFocus(object sender, RoutedEventArgs e)
|
290
|
-
|
291
146
|
=> propertyGrid.SelectedObject = sender;
|
292
147
|
|
293
|
-
|
294
|
-
|
295
148
|
private void DelMenuItem_Click(object sender, RoutedEventArgs e)
|
296
|
-
|
297
149
|
{
|
298
|
-
|
299
150
|
if(sender is MenuItem menuItem)
|
300
|
-
|
301
151
|
{
|
302
|
-
|
303
152
|
if(menuItem.Parent is ContextMenu contextMenu)
|
304
|
-
|
305
153
|
{
|
306
|
-
|
307
154
|
if(contextMenu.PlacementTarget is TextBoxEx textBox)
|
308
|
-
|
309
155
|
{
|
310
|
-
|
311
156
|
propertyGrid.SelectedObject = null;
|
312
|
-
|
313
157
|
textBox.GotFocus -= TextBox_GotFocus;
|
314
|
-
|
315
158
|
canvas.Children.Remove(textBox);
|
316
|
-
|
317
159
|
}
|
318
|
-
|
319
160
|
}
|
320
|
-
|
321
161
|
}
|
322
|
-
|
323
162
|
}
|
324
|
-
|
325
163
|
}
|
326
|
-
|
327
164
|
}
|
328
|
-
|
329
165
|
```
|
330
|
-
|
331
|
-
|
332
166
|
|
333
167
|
---
|
334
168
|
|
335
|
-
|
336
|
-
|
337
169
|
マウスでサイズ変更・移動をちゃんとやるなら、この辺を参考に頑張ってください。
|
338
|
-
|
339
170
|
* 大変古いが公式の [ResizingAdorner のサンプル | Microsoft Docs](https://docs.microsoft.com/ja-jp/previous-versions/dotnet/netframework-3.5/ms771714(v=vs.90)?redirectedfrom=MSDN)(ざっとやってみたが移動とテキストの編集を、どう両立させるかがむずかしい)
|
340
|
-
|
341
171
|
* 「WPF ラバーバンド」あたりで検索
|