2012-01-22 13 views
13

मेरे पास एक टूलबार के साथ एक बटन है जिसमें इसकी सामग्री टूलबार में है। क्लिक करने पर मैं इस बटन को इसके नीचे एक मेनू खोलना चाहता हूं। कैसे?बटन क्लिक होने पर पॉपअप मेनू कैसे खोलें?

<Toolbar> 
      <Button> 
       <Button.Content> 
        <Image Source="../Resources/help.png"></Image> 
       </Button.Content> 
      </Button> 
</Toolbar> 

धन्यवाद !!

+5

क्या आपने कुछ भी कोशिश की है? –

उत्तर

1

वहाँ बहुत से तरीके हैं इस किया पाने के लिए कर रहे हैं और आप इस दृष्टिकोण पर विचार हो सकता ...

<ToolBar DockPanel.Dock="Top"> 
    <MenuItem IsSubmenuOpen="{Binding SomeProperty}"> 
     <MenuItem.Header> 
      <Button Height="28"> 
       <Button.Content> 
        <Image Source="---your image---"></Image> 
       </Button.Content> 
      </Button> 
     </MenuItem.Header> 
     <Menu> 
      <MenuItem Header="Do this" /> 
      <MenuItem Header="Do that"/> 
     </Menu> 
    </MenuItem> 
</ToolBar> 

यह एक MenuItem एक सबमेनू है कि में अपने बटन गिर्द घूमती है। जैसा कि यहां दिखाया गया है, MenuItemIsSubMenuOpen नामक संपत्ति SomeProperty नामक आपके व्यूमोडेल में टाइप बूल की एक अधिसूचित संपत्ति के लिए बाध्य है।

आपको वास्तव में क्या करने की कोशिश कर रहे हैं इसके आधार पर आपको अपना व्यूमोडेल इस संपत्ति को टॉगल करना होगा। आप अपने बटन को टॉगल बटन बनाने पर विचार करना चाहेंगे ताकि उपमेनू को बंद करने में सुविधा मिल सके, अन्यथा आपको अपने व्यूमोडेल में अतिरिक्त व्यवहार करना होगा।

8

मैं इसे खोजने के बाद यह दो समाधान पाया:

1) Split Button in WPF

2) DropDownButtons in WPF

दूसरा समाधान मेरी फ़ेवरिट (स्रोत एंड्रयू विल्किनसन द्वारा वेबसाइट से लिया गया)

है
public class DropDownButton : ToggleButton 
{ 
    // *** Dependency Properties *** 

    public static readonly DependencyProperty DropDownProperty = 
    DependencyProperty.Register("DropDown", 
           typeof(ContextMenu), 
           typeof(DropDownButton), 
           new UIPropertyMetadata(null)); 

    // *** Constructors *** 

    public DropDownButton() { 
    // Bind the ToogleButton.IsChecked property to the drop-down's IsOpen property 

    Binding binding = new Binding("DropDown.IsOpen"); 
    binding.Source = this; 
    this.SetBinding(IsCheckedProperty, binding); 
    } 

    // *** Properties *** 

    public ContextMenu DropDown { 
    get { return (ContextMenu)this.GetValue(DropDownProperty); } 
    set { this.SetValue(DropDownProperty, value); } 
    } 

    // *** Overridden Methods *** 

    protected override void OnClick() { 
    if (this.DropDown != null) { 
     // If there is a drop-down assigned to this button, then position and display it 

     this.DropDown.PlacementTarget = this; 
     this.DropDown.Placement = PlacementMode.Bottom; 

     this.DropDown.IsOpen = true; 
    } 
    } 
} 

उपयोग

एक subclassed Button का उपयोग कर के
<ctrl:DropDownButton Content="Drop-Down"> 
    <ctrl:DropDownButton.DropDown> 
    <ContextMenu> 
     <MenuItem Header="Item 1" /> 
     <MenuItem Header="Item 2" /> 
     <MenuItem Header="Item 3" /> 
    </ContextMenu> 
    </ctrl:DropDownButton.DropDown> 
</ctrl:DropDownButton> 

आशा है कि आप में मदद करता है ...

+3

यह दृष्टिकोण WPF- जैसा नहीं है - संलग्न संपत्ति का उपयोग किया जाना चाहिए, उपclassing नहीं। कारण: 1. शैली अब और काम नहीं करती है 2. आप केवल एक वर्ग से प्राप्त कर सकते हैं लेकिन उसी ऑब्जेक्ट पर कई अलग-अलग संलग्न गुण हैं – Mikhail

+0

@ मिखाइल आप सही हैं, यह केवल एक उदाहरण था – punker76

+1

एक WPF शुरुआत करने वाले के रूप में, ये हैं काम करने के लिए भी अविश्वसनीय रूप से मुश्किल है। बहुत लापता जानकारी। – Chris

30

इसके बजाय, आप संलग्न गुण या एक व्यवहार और का उपयोग बटन कार्यक्षमता ड्रॉप डाउन लागू करने के लिए कर सकते हैं, एक और अधिक WPF की तरह दृष्टिकोण के लिए इसलिए आपको

using System.Windows.Interactivity; 

public class DropDownButtonBehavior : Behavior<Button> 
{ 
    private bool isContextMenuOpen; 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     AssociatedObject.AddHandler(Button.ClickEvent, new RoutedEventHandler(AssociatedObject_Click), true); 
    } 

    void AssociatedObject_Click(object sender, System.Windows.RoutedEventArgs e) 
    { 
     Button source = sender as Button; 
     if (source != null && source.ContextMenu != null) 
     { 
      if (!isContextMenuOpen) 
      { 
       // Add handler to detect when the ContextMenu closes 
       source.ContextMenu.AddHandler(ContextMenu.ClosedEvent, new RoutedEventHandler(ContextMenu_Closed), true); 
       // If there is a drop-down assigned to this button, then position and display it 
       source.ContextMenu.PlacementTarget = source; 
       source.ContextMenu.Placement = PlacementMode.Bottom; 
       source.ContextMenu.IsOpen = true; 
       isContextMenuOpen = true; 
      } 
     }    
    } 

    protected override void OnDetaching() 
    { 
     base.OnDetaching(); 
     AssociatedObject.RemoveHandler(Button.ClickEvent, new RoutedEventHandler(AssociatedObject_Click)); 
    } 

    void ContextMenu_Closed(object sender, RoutedEventArgs e) 
    { 
     isContextMenuOpen = false; 
     var contextMenu = sender as ContextMenu; 
     if (contextMenu != null) 
     { 
      contextMenu.RemoveHandler(ContextMenu.ClosedEvent, new RoutedEventHandler(ContextMenu_Closed)); 
     } 
    } 
} 

उपयोग::

<!-- NOTE: xmlns:i="schemas.microsoft.com/expression/2010/interactivity‌​" --> 
<Button> 
    <i:Interaction.Behaviors> 
     <local:DropDownButtonBehavior/> 
    </i:Interaction.Behaviors> 
    <Button.Content> 
     <StackPanel Orientation="Horizontal"> 
      <Image Source="/DropDownButtonExample;component/Assets/add.png" SnapsToDevicePixels="True" Height="16" Width="16" /> 
      <TextBlock Text="Add"/> 
      <Separator Margin="2,0"> 
       <Separator.LayoutTransform> 
        <TransformGroup> 
         <TransformGroup.Children> 
          <TransformCollection> 
           <RotateTransform Angle="90"/> 
          </TransformCollection> 
         </TransformGroup.Children> 
        </TransformGroup> 
       </Separator.LayoutTransform> 
      </Separator> 
      <Path Margin="2" VerticalAlignment="Center" Width="6" Fill="#FF527DB5" Stretch="Uniform" HorizontalAlignment="Right" Data="F1 M 301.14,-189.041L 311.57,-189.041L 306.355,-182.942L 301.14,-189.041 Z "/> 
     </StackPanel> 
    </Button.Content> 
    <Button.ContextMenu> 
     <ContextMenu> 
      <MenuItem Header="Attribute"/> 
      <MenuItem Header="Setting"/> 
      <Separator/> 
      <MenuItem Header="Property"/> 
     </ContextMenu> 
    </Button.ContextMenu> 
</Button> 

वर्तमान सार स्रोत और उदाहरण 012 'टी बटन शैली को प्रभावित।

+2

यह चाहिए जवाब के रूप में चिह्नित किया जाना चाहिए, अच्छा साफ समाधान! –

+0

मैं इसे क्लिक पर खोलना चाहता हूं और क्लिक पर फिर से बंद करना चाहता हूं, जैसे विजुअल स्टूडियो के स्प्लिट बटन पर ड्रॉपडाउन। प्रत्येक बार जब आप क्लिक करते हैं तो यह कार्यान्वयन खुलता है। मैंने IsOpen =! IsOpen सेट करने की कोशिश की, और जब ईवेंट ट्रिगर होता है (उदा। पूर्वावलोकनमाउसडाउन पर) लेकिन ऐसा लगता है कि एक क्लिक ईवेंट तक पहुंचने से पहले संदर्भ मेनू बंद हो गया है। क्या आप इस रहस्य को हल कर सकते हैं? मुझे यह भी यकीन नहीं है कि यह व्यवहार के भीतर किया जा सकता है। –

+0

यह एक अच्छा सवाल है। चूंकि आप कहते हैं कि 'IsOpen =! IsOpen' काम नहीं कर रहा है, तो आप ContextMenu' Open 'और' बंद 'ईवेंट से अटैचमेंट कर सकते हैं ताकि आप यह निर्धारित कर सकें कि कॉन्टेक्स्टमेनू वास्तव में खुला है या नहीं (संदर्भित कॉन्टेक्स्टमेनू इंस्टेंस नहीं बदलता है)। जहां तक ​​ऐसा होता है, मुझे लगता है कि एक बार जब आप ड्रॉपडाउन बटन को फिर से दबाते हैं, तो तकनीकी रूप से ContextMenu फोकस और बंद हो जाता है, इसलिए व्यवहार कोड निष्पादित होने तक '! IsOpen' प्रयास विफल रहता है। यह देखना दिलचस्प होगा कि विजुअल स्टूडियो वास्तव में यह कैसे करता है। यह इससे कहीं ज्यादा आसान होना चाहिए। – Ryan

8

यदि आपके पास .NET 4 या नए लक्ष्यीकरण की लक्जरी है, तो नई रिबन लाइब्रेरी में RibbonMenuButton है जो ऐसा कर सकता है। 4.5 में यह आपके प्रोजेक्ट में System.Windows.Controls.Ribbon को संदर्भित करने जितना आसान है:

<RibbonMenuButton x:Name="ExampleMenu" SmallImageSource="/Images/Example.png"> 
    <RibbonMenuItem x:Name="ExampleMenuItem" Header="Save" /> 
</RibbonMenuButton> 
+0

WPF के लिए रिबन लाइब्रेरी (.NET 4.0 के लिए एक डाउनलोड लिंक शामिल है): https://msdn.microsoft.com/en-us/library/ff799534.aspx – Chris

संबंधित मुद्दे