【WPF】ビヘイビアのイベントPreviewKeyDown,PreviewKeyUpが発火しない
解決したいこと
C# & WPFでベクターグラフィックスドローイングツールを開発しています。GRAPHERという名前です。
※下にソースコードへの案内を記載しております。よろしければそちらを参照ください。
このツールの、画像を貼り付ける機能を実装しようとしているところです。画面左のツールから「picture」をクリックして、現れるファイルダイアログで、貼り付けたい画像の場所を指定して、実際にキャンバスに画像をドラッグで描くわけです。
単純な画像を貼り付ける機能は簡単に実装できましたが、今度はShiftキーを押している間は、貼り付けようとする画像がアスペクト比が正しくなるように拡大・縮小して描画するようにしたいです。
そこで、コミット0e517deのように実装しました。
発生している問題
しかし、画面上でShiftキーを押下しても、アスペクト比が正しいサイズで描画するようになっていません。
どうやら、PictureBehaviorクラスのPreviewKeyDownイベントハンドラとPreviewKeyUpイベントハンドラが呼び出されていないようです。具体的に言うと、Shiftキーを押したら"set Breakpoint but not fire this event"と書かれているメソッドを実行してほしいのです。
internal class PictureBehavior : Behavior<DesignerCanvas>
{
private Point? _pictureDrawingStartPoint = null;
private string _filename;
private bool _LeftShiftKeyIsPressed;
private bool _RightShiftKeyIsPressed;
public PictureBehavior(string filename)
{
_filename = filename;
}
protected override void OnAttached()
{
this.AssociatedObject.MouseDown += AssociatedObject_MouseDown;
this.AssociatedObject.MouseMove += AssociatedObject_MouseMove;
this.AssociatedObject.PreviewKeyDown += AssociatedObject_PreviewKeyDown;
this.AssociatedObject.PreviewKeyUp += AssociatedObject_PreviewKeyUp;
base.OnAttached();
}
protected override void OnDetaching()
{
this.AssociatedObject.MouseDown -= AssociatedObject_MouseDown;
this.AssociatedObject.MouseMove -= AssociatedObject_MouseMove;
this.AssociatedObject.PreviewKeyDown -= AssociatedObject_PreviewKeyDown;
this.AssociatedObject.PreviewKeyUp -= AssociatedObject_PreviewKeyUp;
base.OnDetaching();
}
private void AssociatedObject_PreviewKeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
//set Breakpoint but not fire this event
if (e.Key == Key.LeftShift)
{
_LeftShiftKeyIsPressed = false;
}
if (e.Key == Key.RightShift)
{
_RightShiftKeyIsPressed = false;
}
}
private void AssociatedObject_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
//set Breakpoint but not fire this event
if (e.Key == Key.LeftShift)
{
_LeftShiftKeyIsPressed = true;
}
if (e.Key == Key.RightShift)
{
_RightShiftKeyIsPressed = true;
}
}
private void AssociatedObject_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
var canvas = AssociatedObject as DesignerCanvas;
if (canvas.SourceConnector == null)
{
if (e.LeftButton != MouseButtonState.Pressed)
_pictureDrawingStartPoint = null;
if (_pictureDrawingStartPoint.HasValue)
{
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(canvas);
if (adornerLayer != null)
{
PictureAdorner adorner = new PictureAdorner(canvas, _pictureDrawingStartPoint, _filename, _LeftShiftKeyIsPressed, _RightShiftKeyIsPressed);
if (adorner != null)
{
adornerLayer.Add(adorner);
}
}
}
}
e.Handled = true;
}
private void AssociatedObject_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
if (e.Source == AssociatedObject)
{
_pictureDrawingStartPoint = e.GetPosition(AssociatedObject);
e.Handled = true;
}
}
}
}
PictureBehaviorクラスのPreviewKeyDownイベントハンドラとPreviewKeyUpイベントハンドラが呼び出されるようにするには何が足りていないのでしょうか。
ちなみに、キャンバスに当たるクラスはDesignerCanvasクラスで、これはDiagramControl.xamlで以下のように使用されています。
<DockPanel>
<DockPanel.LayoutTransform>
<MatrixTransform />
</DockPanel.LayoutTransform>
<Border BorderBrush="Black"
BorderThickness="{Binding BorderThickness}"
Width="{Binding Width, Converter={StaticResource Plus2Converter}}"
Height="{Binding Height, Converter={StaticResource Plus2Converter}}">
<ItemsControl ItemContainerStyleSelector="{x:Static selector:DesignerItemsControlItemStyleSelector.Instance}"
ItemsSource="{Binding Items}"
Width="{Binding Width}"
Height="{Binding Height}"
Background="Transparent">
:
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<control:DesignerCanvas x:Name="designerCanvas"
Width="{Binding Width}"
Height="{Binding Height}"
AllowDrop="True"
Background="White" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
Border(BorderBrush=Black)はキャンバス(描画領域)の境界を示しています。
おおもとのItemsControlインスタンスが描画されるデータを管理する(ItemsSource="{Binding Items}")のですが、こいつはBackground=Transparentに明示的に設定しています。
また、ItemsPanelTemplateのDesignerCanvasではBackground=Whiteに指定しています。
なので、BackgroundをTransparentや他の色に明示的に設定する方法は通用しないようです。
ソースコード
GRAPHER
https://github.com/dhq-boiler/grapher
gitリポジトリ
https://github.com/dhq-boiler/grapher.git
何か私の見落とし、致命的な勘違いなど気づいたところがあれば、回答していただけると助かります。よろしくお願いいたします。