मेरे पास एक विंडो के बाईं तरफ एक WPF TreeView के साथ एमवीवीएम एप्लिकेशन है। सही पर एक विवरण पैनल चयनित पेड़ नोड के आधार पर सामग्री को बदलता है।माउस या कुंजी द्वारा चुने जाने पर कैसे पता लगाएं?
यदि उपयोगकर्ता नोड का चयन करता है, तो विवरण पैनल की सामग्री तुरंत बदल जाती है। यह वांछित है यदि उपयोगकर्ता नोड पर क्लिक करता है, लेकिन यदि मैं कुंजी डाउन/अप का उपयोग करके पेड़ पर नेविगेट करता है तो मैं बदलती सामग्री में देरी करना चाहता हूं। (कम से कम विन XP के तहत विंडोज एक्सप्लोरर के समान व्यवहार) मुझे लगता है कि अगर मुझे माउस या कीबोर्ड के माध्यम से नोड चुना गया है तो मुझे अपने व्यू मॉडेल में पता होना चाहिए।
मैं इसे कैसे प्राप्त कर सकता हूं?
अद्यतन:
यह मेरी पहली पोस्ट इसलिए मुझे यकीन है कि अगर यह सही जगह है नहीं कर रहा हूँ, लेकिन मैं समुदाय पता है कि मैं इस बीच में किया जाने चाहते हैं। मेरा अपना समाधान यहाँ है। मैं एक विशेषज्ञ नहीं हूं इसलिए मुझे नहीं पता कि यह एक अच्छा समाधान है या नहीं। लेकिन यह मेरे लिए काम करता है और अगर मैं दूसरों की मदद करता हूं तो मैं खुश रहूंगा। बगफिक्स, सुधार या बेहतर समाधान की अत्यधिक सराहना की जाती है।
मैं HasMouseFocus ...
जुड़ी संपत्ति नीचे बनाया (पहले मैं MouseEnterEvent थे, लेकिन यह अच्छी तरह से काम नहीं करता है उपयोगकर्ता कुंजी ऊपर/नीचे के साथ पेड़ नेविगेट करता है और माउस सूचक किसी भी navigated पेड़ से अधिक बेतरतीब ढंग से है अगर आइटम, क्योंकि उस मामले में विवरण तत्काल अद्यतन हो जाता है।)
public static bool GetHasMouseFocus(TreeViewItem treeViewItem)
{
return (bool)treeViewItem.GetValue(HasMouseFocusProperty);
}
public static void SetHasMouseFocus(TreeViewItem treeViewItem, bool value)
{
treeViewItem.SetValue(HasMouseFocusProperty, value);
}
public static readonly DependencyProperty HasMouseFocusProperty =
DependencyProperty.RegisterAttached(
"HasMouseFocus",
typeof(bool),
typeof(TreeViewItemProperties),
new UIPropertyMetadata(false, OnHasMouseFocusChanged)
);
static void OnHasMouseFocusChanged(
DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
TreeViewItem item = depObj as TreeViewItem;
if (item == null)
return;
if (e.NewValue is bool == false)
return;
if ((bool)e.NewValue)
{
item.MouseDown += OnMouseDown;
item.MouseLeave += OnMouseLeave;
}
else
{
item.MouseDown -= OnMouseDown;
item.MouseLeave -= OnMouseLeave;
}
}
/// <summary>
/// Set HasMouseFocusProperty on model of associated element.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
static void OnMouseDown(object sender, MouseEventArgs e)
{
if (sender != e.OriginalSource)
return;
TreeViewItem item = sender as TreeViewItem;
if ((item != null) & (item.HasHeader))
{
// get the underlying model of current tree item
TreeItemViewModel header = item.Header as TreeItemViewModel;
if (header != null)
{
header.HasMouseFocus = true;
}
}
}
/// <summary>
/// Clear HasMouseFocusProperty on model of associated element.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
static void OnMouseLeave(object sender, MouseEventArgs e)
{
if (sender != e.OriginalSource)
return;
TreeViewItem item = sender as TreeViewItem;
if ((item != null) & (item.HasHeader))
{
// get the underlying model of current tree item
TreeItemViewModel header = item.Header as TreeItemViewModel;
if (header != null)
{
header.HasMouseFocus = false;
}
}
}
... और TreeView.ItemContainerStyle
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}" >
<!-- These Setters binds some properties of a TreeViewItem to the TreeViewItemViewModel. -->
<Setter Property="IsExpanded" Value="{Binding Path=IsExpanded, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Setter Property="ToolTip" Value="{Binding Path=CognosBaseClass.ToolTip}"/>
<!-- These Setters applies attached behaviors to all TreeViewItems. -->
<Setter Property="properties:TreeViewItemProperties.PreviewMouseRightButtonDown" Value="True" />
<Setter Property="properties:TreeViewItemProperties.BringIntoViewWhenSelected" Value="True" />
<Setter Property="properties:TreeViewItemProperties.HasMouseFocus" Value="True" />
</Style>
</TreeView.ItemContainerStyle>
पर लागू कर जहां गुण मेरी संलग्न संपत्ति का मार्ग है।
xmlns:properties="clr-namespace:WPF.MVVM.AttachedProperties;assembly=WPF.MVVM"
मेरी ViewModel में तो फिर, अगर HasMousefocusProperty सच है, मैं उसके विवरण फलक (GridView) तुरंत अपडेट। यदि झूठी है तो मैं बस एक डिस्पैचर टाइमर शुरू करता हूं और वर्तमान में चयनित आइटम को टैग के रूप में लागू करता हूं। 500ms के अंतराल के बाद टिक-इवेंट विवरण लागू करता है, लेकिन केवल तभी चयनित आइटम टैग के समान ही होता है।
/// <summary>
/// This property is beeing set when the selected item of the tree has changed.
/// </summary>
public TreeItemViewModel SelectedTreeItem
{
get { return Property(() => SelectedTreeItem); }
set
{
Property(() => SelectedTreeItem, value);
if (this.SelectedTreeItem.HasMouseFocus)
{
// show details for selected node immediately
ShowGridItems(value);
}
else
{
// delay showing details
this._selctedNodeChangedTimer.Stop();
this._selctedNodeChangedTimer.Tag = value;
this._selctedNodeChangedTimer.Start();
}
}
}
निम्न एसओ प्रश्न में शीर्ष दो उत्तरों कीबाइंडिंग समस्या के साथ सौदा: http://stackoverflow.com/a/7086853/1416258 और http://stackoverflow.com/a/918062/1416258 जहां तक आपका व्यक्तिगत स्थिति, या तो चारों ओर खेलते हैं या किसी के लिए आपको मछली देने का इंतजार करते हैं। –
बहुत धन्यवाद @ जीओइस्ट। जैसे ही उपयोगकर्ता निर्दिष्ट कुंजी दबाता है, मैं एक कैमैंड बाइंडिंग का उपयोग करके अपने व्यू मॉडेल में एक झंडा सेट कर सकता हूं। लेकिन मुझे इस ध्वज को फिर से साफ़ करना होगा जब (या पहले) तो उपयोगकर्ता एक और पेड़ नोड का चयन करता है। कोई विचार? – AelanY
@ एलेनवाई हाँ, आप सही हैं कि आपको इस ध्वज को रीसेट करने की देखभाल करनी होगी, सबसे अच्छी जगह यह तर्क हो सकता है कि आप अपने विवरण पैनल को रीफ्रेश शुरू कर रहे हैं। – akjoshi