WPF drag過程中顯示ToolTip.

在drag/drop過程中,我們在判斷出over的元素上是否可以接受drag的東西之後,通常是通過鼠標的樣式簡單告訴用戶這個元素不接受現在drag的內容,但是用戶通常不知道具體的原因,有時候爲了增強客戶體驗,會在over的過程中顯示tooltip來告訴用戶爲什麼不能接受drag的東西或者告訴用戶over的元素是什麼東西,特別是一些繪圖或者其他一些複雜的應用軟件,這種方式比較廣泛。

WPF 給各種控件提供了ToolTip屬性,可以通過設置該屬性的值來決定鼠標Over到控件的時候要顯示什麼內容,但是在Drag的過程中卻不能觸發MouseOver事件,觸發的是DragOver事件,那就需要Popup 來實現該效果,下面是根據自己的經驗來簡單設計了一個Popup控件實現tooltip功能。

1. 在Xaml中增加Popup控件以及進行數據綁定

        <Popup x:Name="toolTip" IsOpen="{Binding ShowToolTip, Mode=OneWay}" AllowsTransparency="True" 
            Placement="Relative" HorizontalOffset="{Binding ToolTipPos.X}" VerticalOffset="{Binding ToolTipPos.Y}">
            <TextBlock Foreground="Red" Text="{Binding DragElement.Description}"></TextBlock>
        </Popup>


注:在Popup的屬性設置中特別注意Placement的屬性值,詳細信息可以查看MSDN 怎樣設置Placement屬性

2. 在ViewModel中要注意屬性值的計算

        private Point _tooltipPos;
        public Point ToolTipPos
        {
            get { return _tooltipPos; }
            set
            {
                if (_tooltipPos == value)
                    return;
                if (Math.Abs(_tooltipPos.X - 15 - value.X) > 15 || Math.Abs(_tooltipPos.Y - 15 - value.Y) > 15)
                {
                    // why reduce 15? because if position the popup window to current cursor location, 
                    //if mouse moving when drag/drop, the mouse will be on popup window, so the user's experience is not good.
                    _tooltipPos = value;
                    _tooltipPos.Offset(15, 15);
                    RaisePropertyChanged("ToolTipPos");
                }
            }
        }


注意ToolTipPos的Set值的設置,實際上value是光標當前的位置,爲什麼要對改值Offset(15,15)?主要是爲了在Popup窗口顯示的時候,要保證光標所Over的控件是原來的控件,如果不進行offset,在某些細微移動的過程中可能出現DragOver的對象由原來的控件跟popup窗口之間切換。

        private bool _showToolTip;
        public bool ShowToolTip
        {
            get { return _showToolTip; }
            set
            {
                if(_showToolTip == value)
                    return;
                _showToolTip = value;
                RaisePropertyChanged("ShowToolTip");
            }
        }



該屬性決定了Popup窗口是否要顯示,需要在DragOver事件處理函數中進行設置爲True. 在dragover對象的mousemove處理函數中設置該值爲false,保證Popup消失。


3. DragOver的過程中獲取鼠標的位置,設置Popup窗口的target屬性。

            this.toolTip.PlacementTarget = this.SelectedEmployees;
            this.ToolTipPos = e.GetPosition(SelectedEmployees);
            ShowToolTip = true;
注: e 爲dragover過程中參數DragEventArgs e,  在獲取鼠標位置的時候不要用Mouse.GetPosition(IInputElement ),因爲在drag過程中對鼠標是在DragOver事件中管理的, 用Mouse.GetPosition(IInputElement)不能獲得準確的值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章