トップ回答者
ButtonオブジェクトをDragDeltaイベントで移動させたい

質問
-
お世話になります。
表題の通りなのですが、ButtonオブジェクトをDragDeltaイベントを使って移動させたいのです。
Labelや、TextBlockなどは移動出来ましたが、ButtonやTextBoxは移動が出来ませんでした。
ButtonやTextBoxなどフォーカスがオブジェクト自体に移ってしまう物は移動が出来ないのでしょうか?
Buttonを移動させたい場合どうすべきでしょうか?
宜しくお願い致します。<Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"> <Canvas> <Thumb DragDelta="DragDelta" Canvas.Left="12" Canvas.Top="12" Height="250" Width="250"> <Thumb.Template> <ControlTemplate> <!--ドラッグ対象のオブジェクトを定義する--> <!-- 移動OK --> <TextBlock Text="これはTextBlockです。" Width="150" Height="20" Background="Aqua" /> <!--<Label Content="これはLabelです。" Width="150" Height="20" Background="Aqua" />--> <!-- 移動NG --> <!--<Button Content="これはButtonです。" Width="150" Height="20" Background="Aqua" />--> <!--<TextBox Text="これはTextBoxです。" Width="150" Height="20" Background="Aqua" />--> </ControlTemplate> </Thumb.Template> </Thumb> </Canvas> </Window>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; //Thumbコントロールへの参照追加 using System.Windows.Controls.Primitives; namespace WpfApplication1 { /// <summary> /// Window1.xaml の相互作用ロジック /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); } //Thumbコントロールのドラッグイベント処理 private void DragDelta(object sender, DragDeltaEventArgs e) { var thumb = sender as Thumb; if (thumb == null) return; //ドラッグ量に応じてThumbコントロールを移動する Canvas.SetLeft(thumb, Canvas.GetLeft(thumb) + e.HorizontalChange); Canvas.SetTop(thumb, Canvas.GetTop(thumb) + e.VerticalChange); } } }
回答
-
Preview系のイベントで処理してやるとお手軽にできたり。
<Thumb DragDelta="DragDelta" Canvas.Left="12" Canvas.Top="12" Height="250" Width="250" PreviewMouseLeftButtonDown="Thumb_PreviewMouseLeftButtonDown"> <Thumb.Template> <ControlTemplate> <!--ドラッグ対象のオブジェクトを定義する--> <!-- 移動OK --> <!--TextBlock Text="これはTextBlockです。" Width="150" Height="20" Background="Aqua" />--> <!--<Label Content="これはLabelです。" Width="150" Height="20" Background="Aqua" />--> <!-- 移動NG --> <!--<Button Content="これはButtonです。" Width="150" Height="20" Background="Aqua" />--> <TextBox Text="これはTextBoxです。" Width="150" Height="20" Background="Aqua" /> </ControlTemplate> </Thumb.Template> </Thumb>
//Thumbコントロールのドラッグイベント処理 private void DragDelta(object sender, DragDeltaEventArgs e) { var thumb = sender as Thumb; if (thumb == null) return; //ドラッグ量に応じてThumbコントロールを移動する Canvas.SetLeft(thumb, Canvas.GetLeft(thumb) + e.HorizontalChange); Canvas.SetTop(thumb, Canvas.GetTop(thumb) + e.VerticalChange); } private void Thumb_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Thumb thumb = (Thumb)sender; if (Keyboard.PrimaryDevice.Modifiers== ModifierKeys.Alt) { var mi=typeof(Thumb).GetMethod("OnMouseLeftButtonDown" , System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); mi.Invoke(thumb, new object[] { e }); } }
#私はDrag処理のときはThumb使わずに自前の添付ビヘイビアでやってるので、キーの種類に応じて回転なんかもさせたりしてます。
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク sumi_sumi 2012年9月14日 5:09
-
少し無理やりな感じがしますが、RoutedEvent を使って実装してみました。一応それっぽい動きになっていると思いますがお試しください。
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Canvas> <Thumb DragDelta="DragDelta" Canvas.Left="12" Canvas.Top="12" Name="thumb" > <Thumb.Template> <ControlTemplate> <Grid Width="180" Height="38" Background="Aqua" Name="grid" Button.PreviewMouseDown="button_MouseDown" Button.PreviewMouseMove="button_MouseMove" > <Button Content="これはButtonです。" Margin="8" Name="button" /> </Grid> </ControlTemplate> </Thumb.Template> </Thumb> </Canvas> </Window>
using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Input; namespace WpfApplication1 { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } //Thumbコントロールのドラッグイベント処理 private void DragDelta(object sender, DragDeltaEventArgs e) { var thumb = sender as Thumb; if (thumb == null) return; //ドラッグ量に応じてThumbコントロールを移動する Canvas.SetLeft(thumb, Canvas.GetLeft(thumb) + e.HorizontalChange); Canvas.SetTop(thumb, Canvas.GetTop(thumb) + e.VerticalChange); } Point _pos; private void button_MouseDown(object sender, MouseButtonEventArgs e) { var button = e.Source as Button; if (button != null) { _pos = this.PointToScreen(Mouse.GetPosition(this)); } } private void button_MouseMove(object sender, MouseEventArgs e) { var button = e.Source as Button; if (button != null) { if (button.IsPressed) { var pos = this.PointToScreen(Mouse.GetPosition(this)); this.thumb.RaiseEvent(new DragDeltaEventArgs(pos.X -_pos.X, pos.Y -_pos.Y)); _pos = this.PointToScreen(Mouse.GetPosition(this)); } } } } }
ひらぽん http://d.hatena.ne.jp/hilapon/
- 回答としてマーク sumi_sumi 2012年9月14日 5:09
すべての返信
-
> Buttonを移動させたい場合どうすべきでしょうか?
厄介ですねぇ。代替案としてパネルに Button を配置し、パネルをドラッグすることなら思い浮かぶのですが、この場合パネルは移動できても Button を掴んでの移動はできませんでした。
<Canvas> <ListBox Canvas.Left="21" Canvas.Top="142" Height="154" Name="listBox1" Width="308" /> <Thumb DragDelta="DragDelta" Canvas.Left="12" Canvas.Top="12" > <Thumb.Template> <ControlTemplate> <Grid Width="180" Height="38" Background="Aqua" > <Button Content="これはButtonです。" Margin="8" /> </Grid> </ControlTemplate> </Thumb.Template> </Thumb> </Canvas>
ひらぽん http://d.hatena.ne.jp/hilapon/
-
少し無理やりな感じがしますが、RoutedEvent を使って実装してみました。一応それっぽい動きになっていると思いますがお試しください。
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Canvas> <Thumb DragDelta="DragDelta" Canvas.Left="12" Canvas.Top="12" Name="thumb" > <Thumb.Template> <ControlTemplate> <Grid Width="180" Height="38" Background="Aqua" Name="grid" Button.PreviewMouseDown="button_MouseDown" Button.PreviewMouseMove="button_MouseMove" > <Button Content="これはButtonです。" Margin="8" Name="button" /> </Grid> </ControlTemplate> </Thumb.Template> </Thumb> </Canvas> </Window>
using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Input; namespace WpfApplication1 { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } //Thumbコントロールのドラッグイベント処理 private void DragDelta(object sender, DragDeltaEventArgs e) { var thumb = sender as Thumb; if (thumb == null) return; //ドラッグ量に応じてThumbコントロールを移動する Canvas.SetLeft(thumb, Canvas.GetLeft(thumb) + e.HorizontalChange); Canvas.SetTop(thumb, Canvas.GetTop(thumb) + e.VerticalChange); } Point _pos; private void button_MouseDown(object sender, MouseButtonEventArgs e) { var button = e.Source as Button; if (button != null) { _pos = this.PointToScreen(Mouse.GetPosition(this)); } } private void button_MouseMove(object sender, MouseEventArgs e) { var button = e.Source as Button; if (button != null) { if (button.IsPressed) { var pos = this.PointToScreen(Mouse.GetPosition(this)); this.thumb.RaiseEvent(new DragDeltaEventArgs(pos.X -_pos.X, pos.Y -_pos.Y)); _pos = this.PointToScreen(Mouse.GetPosition(this)); } } } } }
ひらぽん http://d.hatena.ne.jp/hilapon/
- 回答としてマーク sumi_sumi 2012年9月14日 5:09
-
Preview系のイベントで処理してやるとお手軽にできたり。
<Thumb DragDelta="DragDelta" Canvas.Left="12" Canvas.Top="12" Height="250" Width="250" PreviewMouseLeftButtonDown="Thumb_PreviewMouseLeftButtonDown"> <Thumb.Template> <ControlTemplate> <!--ドラッグ対象のオブジェクトを定義する--> <!-- 移動OK --> <!--TextBlock Text="これはTextBlockです。" Width="150" Height="20" Background="Aqua" />--> <!--<Label Content="これはLabelです。" Width="150" Height="20" Background="Aqua" />--> <!-- 移動NG --> <!--<Button Content="これはButtonです。" Width="150" Height="20" Background="Aqua" />--> <TextBox Text="これはTextBoxです。" Width="150" Height="20" Background="Aqua" /> </ControlTemplate> </Thumb.Template> </Thumb>
//Thumbコントロールのドラッグイベント処理 private void DragDelta(object sender, DragDeltaEventArgs e) { var thumb = sender as Thumb; if (thumb == null) return; //ドラッグ量に応じてThumbコントロールを移動する Canvas.SetLeft(thumb, Canvas.GetLeft(thumb) + e.HorizontalChange); Canvas.SetTop(thumb, Canvas.GetTop(thumb) + e.VerticalChange); } private void Thumb_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Thumb thumb = (Thumb)sender; if (Keyboard.PrimaryDevice.Modifiers== ModifierKeys.Alt) { var mi=typeof(Thumb).GetMethod("OnMouseLeftButtonDown" , System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); mi.Invoke(thumb, new object[] { e }); } }
#私はDrag処理のときはThumb使わずに自前の添付ビヘイビアでやってるので、キーの種類に応じて回転なんかもさせたりしてます。
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク sumi_sumi 2012年9月14日 5:09