WPF彈出控件很好,但在我看來有點受限。有沒有辦法在打開時拖動一個彈出窗口(就像使用Windows的DragMove()方法)?拖動WPF彈出控件
可以在此沒有大的問題做或做我必須寫在彈出類自己的替代品? 感謝
WPF彈出控件很好,但在我看來有點受限。有沒有辦法在打開時拖動一個彈出窗口(就像使用Windows的DragMove()方法)?拖動WPF彈出控件
可以在此沒有大的問題做或做我必須寫在彈出類自己的替代品? 感謝
下面是使用Thumb的簡單解決方案。在XAML
XAML:
<Popup x:Class="PopupTest.DraggablePopup" ...>
<Canvas x:Name="ContentCanvas">
</Canvas>
</Popup>
C#:
public partial class DraggablePopup : Popup
{
public DraggablePopup()
{
var thumb = new Thumb
{
Width = 0,
Height = 0,
};
ContentCanvas.Children.Add(thumb);
MouseDown += (sender, e) =>
{
thumb.RaiseEvent(e);
};
thumb.DragDelta += (sender, e) =>
{
HorizontalOffset += e.HorizontalChange;
VerticalOffset += e.VerticalChange;
};
}
}
沒有爲彈出沒有DragMove。只是一個小小的工作,你可以添加很多改進。
<Popup x:Name="pop" IsOpen="True" Height="200" Placement="AbsolutePoint" Width="200">
<Rectangle Stretch="Fill" Fill="Red"/>
</Popup>
在後面的代碼,添加此mousemove事件
pop.MouseMove += new MouseEventHandler(pop_MouseMove);
void pop_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
pop.PlacementRectangle = new Rect(new Point(e.GetPosition(this).X,
e.GetPosition(this).Y),new Point(200,200));
}
}
Private Point startPoint;
private void Window_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
startPoint = e.GetPosition(null);
}
private void Window_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Point relative = e.GetPosition(null);
Point AbsolutePos = new Point(relative.X + this.Left, relative.Y + this.Top);
this.Top = AbsolutePos.Y - startPoint.Y;
this.Left = AbsolutePos.X - startPoint.X;
}
}
這適用於拖我的窗口,但就像是如果我把鼠標移動到快告訴,它會走出的窗口,並停止提高事件。沒有提到拖拽根本不流暢。有誰知道如何正確地做到這一點,漂亮和平滑的拖動,而不會拖動太快拖動它?如果可能的話發佈一個簡單的例子,除了可以讓像我這樣的初學者在代碼中丟失的整個教程。謝謝!
你可以捕捉鼠標,以避免你提到的問題,當鼠標離開窗口 – 2011-05-02 11:02:55
實現這一目標的另一種方法是設置彈出窗口的位置,以MousePoint。這使彈出窗口最初出現在鼠標光標的位置。
那麼您可以使用拇指或MouseMove事件,設置彈出的HorizontalOffset & VerticalOffset。這些屬性會在用戶拖拽Popup時將其從原始位置移開。
記住將HorizontalOffset和VerticalOffset回零,以便下次使用彈出窗口!
與失去鼠標的問題走得太快時,能夠得到解決
這是從MSDN採取:
新窗口包含兒童Popup的內容。
彈出式窗口控制,以保持它的子內容的邏輯子對象的引用。當新窗口被創建時,彈出窗口的內容變成窗口的可視子窗口,並保持爲彈出窗口的邏輯子窗口。相反,Popup仍然是其子內容的合乎邏輯的父項。
在換句話說,在彈出的子顯示在獨立的窗口。
因此,當嘗試以下操作:
Popup.CaptureMouse()
正在捕獲包裝窗口,而不是彈出窗口本身。而是使用Popup.Child.CaptureMouse()
捕獲實際的彈出窗口。
所有其他事件都應該使用Popup.Child
註冊。
像Popup.Child.MouseMove
,Popup.Child.LostCapture
等
這已經過測試,運行完美
** **哎呦!不,請使用[`Thumb`](http://msdn.microsoft.com/en-us/library/ms749252%28VS.100%29.aspx)及其`DragDelta`事件(選擇「DragStarted」/「 `DragCompleted`,如果你想管理狀態)。它更高效,不會像以上例子那樣碎片化內存,並且不會冒失去鼠標的風險。這就是正確的拖動方式:)例子見[這裏](http://www.codeproject.com/KB/WPF/TubePlanner.aspx)。 – RedGlyph 2010-09-02 19:37:33
我同意,我給出的解決方案只是一個破解,正如你所說DragDelta比MoveMove更高效。 – 2010-09-02 21:16:44
但是,如果你不想濫用彈出窗口作爲拇指(我想我的意思是在RedGlyphs評論中),但想要移動更復雜的彈出窗口(例如視頻覆蓋圖)。在我的場景中使用明確的窗口不是選項。 – 2011-07-26 13:39:57