2009-04-10 19 views
9

मैं कुछ एक्सएएमएल पर एक डब्ल्यूपीएफ एप्लीकेशन के लिए काम कर रहा हूं और मुझे यह करने में कुछ परेशानी हो रही है जो मैं चाहता हूं।डब्ल्यूपीएफ: टूलबार में नेस्टेड मेनू इटम्स

<!-- Tool Bar Tray --> 
<ToolBarTray Name="toolBarTray1" DockPanel.Dock="Top"> 
    <!-- File And Edit Tools --> 
    <ToolBar Name="toolBar1" Band="1" BandIndex="1"> 
     <!-- Regular Items --> 
     <Button>A</Button> 
     <Button>B</Button> 
     <!-- Overflow Menu For Special Items --> 
     <MenuItem ToolBar.OverflowMode="Always" Header="Special Items"> 
      <MenuItem Header="C"/> 
      <MenuItem Header="D"/> 
     </MenuItem> 
    </ToolBar> 
</ToolBarTray> 

जब मैं अपने उपकरण पट्टी के अतिप्रवाह बटन पर क्लिक करें, "विशेष आइटम" MenuItem एक छोटे से तीर के साथ आगे दिखाई देने, नेस्टेड तत्वों का संकेत: यहाँ मेरी XAML का एक नमूना है। हालांकि, जब मैं "विशेष आइटम" पर माउस को घुमाता हूं या उस पर क्लिक करने का प्रयास करता हूं, तो मेनूइटम "सी" और "डी" प्रदर्शित नहीं होते हैं।

मैं उम्मीद कर रहा था कि मेनूइटम सिर्फ एक मेनू के बाहर काम करेगा, लेकिन मैंने सीधे मामले में सीधे आगे बढ़ने की कोशिश की। इन मेनू आइटम्स को एक मेनू के अंदर और इसके बजाय, इस मेनू को टूलबार को प्रदान करना। ओवरफ्लोमोड = "हमेशा" संपत्ति कुछ अवांछित स्टाइल बनाती है। तीर अब मौजूद नहीं है, उप-मेनू को सक्रिय करने के लिए "विशेष आइटम" प्रविष्टि को क्लिक करने की आवश्यकता है और उप-मेनू स्थिति थोड़ा दिखता है।

क्या किसी को पता है कि क्या हो रहा है?

संपादित करें: ओवरफ़्लो में मेनू जोड़ना ठीक उसी प्रकार का उत्पादन कर रहा है जो मैंने अनुरोध किया है (बड़ा आश्चर्य)। मैं बाद में शीर्ष-स्तरीय शीर्षलेखों और आइटम्स को उप-मेनू स्तर में परिवर्तित करने का एक तरीका है। मैं समाधान (नीचे) के लिए MSDN पर इस नियंत्रण टेम्पलेट उदाहरण की ओर मुड़ गया हूं।

संपादित करें, संपादित करें: @gcores (टिप्पणी चर्चा): वास्तव में? क्या मैं कुछ भूल रहा हूँ?

<ToolBar Name="toolBar1" Band="1" BandIndex="4"> 
    <!-- Displayed Buttons --> 
    <Button>A</Button> 
    <Button>B</Button> 
    <!-- Special Items Menu --> 
    <Menu ToolBar.OverflowMode="Always" > 
     <MenuItem Style="{StaticResource MenuItemStyle}" Header="Special"> 
      <MenuItem Header="C"/> 
      <MenuItem Header="D"/> 
     </MenuItem> 
    </Menu> 
</ToolBar> 

यह स्निपेट मेरे लिए काम नहीं करता है। मुझे प्रदर्शित करने के लिए उप-मेनू के लिए 'विशेष' पर क्लिक करना होगा।

उत्तर

0

इस व्यवहार को उत्पन्न करने के करीब आने का एकमात्र तरीका ओवरफ्लो में एक मेनू बनाना था जिसमें एक मेनू आइटम था जिसका हेडर स्वयं "मेनू" नामक एक और मेनू आइटम था और उचित बच्चों को शामिल करता था। यह इरादे के रूप में काम करता था लेकिन विचित्र लग रहा था (यह कस्टम टेम्पलेट्स द्वारा उपचार किया जा सकता है) और यह भी एक विशाल हैक की तरह लगता है। ऐसा करने का एकमात्र "उचित" तरीका है जिसके बारे में मैं सोच सकता हूं कि आपका खुद का मेनू इटिम-जैसे नियंत्रण होगा जो कॉन्टेक्स्टमेनू या पॉपअप को पॉप करता है, क्योंकि मुझे नहीं लगता कि कस्टम कंट्रोल टेम्पलेट डिफ़ॉल्ट व्यवहार को बदल सकता है एक मेनू ताकि शीर्ष स्तर की वस्तु पर क्लिक की आवश्यकता न हो।

1

और पढ़ने के बाद, मैं जिस समाधान का उपयोग कर रहा हूं वह नीचे है।

<!-- Resource Dictionary Stuff --> 

<!-- Some Brushes --> 
<SolidColorBrush x:Key="Brush_1" 
    Color="White" /> 

<LinearGradientBrush x:Key="Brush_2" 
    StartPoint="0 0" 
    EndPoint="0 1"> 

    <GradientStop 
     Color="White" 
     Offset="0"/> 

    <GradientStop 
     Color="DarkSeaGreen" 
     Offset="1"/> 

</LinearGradientBrush> 

<SolidColorBrush x:Key="Brush_3" 
    Color="DarkOliveGreen"/> 

<!-- Custom MenuItem - Top Level Header - Style 1 --> 
<Style x:Key="MenuItem_TLH_Style1" 
    TargetType="MenuItem"> 

    <!--<EventSetter Event="PreviewMouseDown" Handler="DoNothing"/>--> 

    <Setter Property="Template"> 
     <Setter.Value> 

      <ControlTemplate x:Name="ControlTemplate" 
       TargetType="MenuItem"> 

       <!-- A headered text that may display a submenu 
        on a trigger. This submenu is the host for a 
        menu item's items. --> 
       <Border x:Name="BoundaryBorder" 
        Background="{StaticResource Brush_1}" 
        BorderThickness="1"> 

        <Grid x:Name="ContainerGrid"> 

         <ContentPresenter x:Name="HeaderContent" 
          Margin="6 3 6 3" 
          ContentSource="Header" 
          RecognizesAccessKey="True"/> 

         <Popup x:Name="SubmenuPopup" 
          Placement="Bottom" 
          IsOpen="{TemplateBinding IsSubmenuOpen}" 
          AllowsTransparency="True" 
          Focusable="False" 
          PopupAnimation="Fade"> 

          <Border x:Name="SubmenuBoundaryBorder" 
           SnapsToDevicePixels="True" 
           Background="{StaticResource Brush_1}" 
           BorderBrush="{StaticResource SolidBorderBrush}" 
           BorderThickness="1"> 

           <StackPanel x:Name="ItemsStackPanel" 
            IsItemsHost="True" 
            KeyboardNavigation.DirectionalNavigation="Cycle"/> 

          </Border> 
         </Popup> 
        </Grid> 
       </Border> 

       <ControlTemplate.Triggers> 

        <!-- --> 
        <Trigger 
         Property="IsSuspendingPopupAnimation" 
         Value="true"> 

         <Setter 
          TargetName="SubmenuPopup" 
          Property="PopupAnimation" 
          Value="Fade"/> 

        </Trigger> 

        <!-- On mouse-over, show the submenu and highlight the header. --> 
        <Trigger 
         Property="IsMouseOver" 
         Value="true"> 

         <Setter 
          TargetName="BoundaryBorder" 
          Property="Background" 
          Value="{StaticResource Brush_2}"/> 

         <Setter 
          TargetName="BoundaryBorder" 
          Property="BorderBrush" 
          Value="{StaticResource Brush_3}"/> 

         <Setter 
          Property="IsSubmenuOpen" 
          Value="true"/> 

         <!-- sloppy? --> 
         <Setter 
          TargetName="SubmenuPopup" 
          Property="IsOpen" 
          Value="true"/> 

        </Trigger> 

        <Trigger 
         SourceName="SubmenuPopup" 
         Property="AllowsTransparency" 
         Value="true"> 

         <Setter 
          TargetName="SubmenuBoundaryBorder" 
          Property="CornerRadius" 
          Value="0 0 4 4"/> 

         <Setter 
          TargetName="SubmenuBoundaryBorder" 
          Property="Padding" 
          Value="0 0 0 3"/> 

        </Trigger> 

        <!-- Visually indicate an unaccessible menu item. --> 
        <Trigger 
         Property="IsEnabled" 
         Value="false"> 

         <Setter 
          Property="Foreground" 
          Value="{StaticResource DisabledForegroundBrush}"/> 

        </Trigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

<!-- ... --> 

<!-- Inside a window XAML file --> 

<!-- Tool Bar Tray --> 
<ToolBarTray x:Name="toolBarTray1" 
    DockPanel.Dock="Top"> 

    <!-- File And Edit Tools --> 
    <ToolBar x:Name="toolBar1" 
     Band="1" BandIndex="1"> 

     <!-- Displayed Buttons --> 
     <Button x:Name="ButtonA" 
      Content="A"/> 

     <Button x:Name="ButtonB" 
      Content="B"/> 

     <!-- Overflow Menu For Special Items --> 
     <Menu x:Name="OverflowMenu" 
      ToolBar.OverflowMode="Always"> 

      <MenuItem x:Name="SpecialsMenuItem" 
       Style="{StaticResource MyStyle}" 
       Header="Special Items"> 

       <MenuItem x:Name="CMenuItem" 
        Header="C"> 

        <MenuItem x:Name="DMenuItem" 
         Header="D"/> 

       </MenuItem> 
      </MenuItem> 
     </Menu> 
    </ToolBar> 
</ToolBarTray> 

मैं नहीं बल्कि क्लिक करें घटना से निपटने की तुलना में, एक माउस-ओवर पर 'SubmenuPopup' के व्यवहार पर हमला। मैं इसे और अधिक समझना चाहता हूं, इसलिए मैंने ट्रिगर के इस हिस्से को टिप्पणी करने और एक ईवेंट हैंडलर जोड़ने की कोशिश की जो 'पूर्वावलोकनमाउसडाउन' ईवेंट पर 'DoNothing()' विधि को कॉल करता है। यह पता चला है कि मुझे कुछ याद आ रहा है और मुझे लगता है कि यह ध्यान केंद्रित करने और/या कैसे मेनू अपने आइटम संग्रह को संभालने से संबंधित है। "विशेष आइटम" मेनू आइटम पर क्लिक करते समय 'DoNothing()' (routedEventArgs.Handled = true) के बाद किसी ईवेंट को प्रसारित करने की इजाजत नहीं दी जाती है। हालांकि, अगर कोई मेनू से दूर निकलता है या कोई अन्य मेनू आइटम जोड़ता है और उसके बाद उस पर क्लिक किया जाता है, तो होवर व्यवहार बंद या बंद और बंद कर दिया जा सकता है।

2

एक और समाधान मौजूदा टेम्पलेट्स का उपयोग करना और सबमेनूहेडर के टेम्पलेट के साथ टॉपलेवलहेडर के लिए टेम्पलेट को ओवरराइड करना है।

<Style x:Key="MenuItemStyle" TargetType="{x:Type MenuItem}"> 
    <Style.Triggers> 
    <Trigger Property="Role" Value="TopLevelHeader"> 
     <Setter Property="Template" 
       Value="{StaticResource {x:Static MenuItem.SubmenuHeaderTemplateKey}}"/> 
    </Trigger> 
    </Style.Triggers> 
</Style> 

और इस शैली का उपयोग अपने शीर्ष स्तर मेनूइटम में करें। यह आपके कोड को सरल बनाना चाहिए।

संपादित: आप सही हैं, यह केवल जब आप उस पर क्लिक करें काम करता है (, कैसे मैं अपने आप को आश्वस्त यह काम किया पता नहीं है खेद :))। यह कार्यक्षमता शीर्ष लेवलमेनू की तरह है, भले ही टेम्पलेट अन्यथा कहता है, यह काफी उलझन में है।

केवल एक चीज जो मैं सोच सकता हूं वह है IMenuOver पर सबमेनू दिखाने और क्लिक ईवेंट को संभालने के लिए एक ट्रिगर जोड़ रहा है, इसलिए यह कुछ भी नहीं करता है लेकिन मुझे नहीं पता कि यह कितना अच्छा काम करेगा।

+0

आप जानते हैं, यह वही है जो मैं पहले करने की कोशिश कर रहा था। मैं एमएसडीएन पर विचार कर रहा था और भूमिका संपत्ति पाई, लेकिन मुझे इसे बदलने का सही तरीका नहीं पता था। मैंने तब पाया कि मैंने ऊपर पोस्ट किए गए त्वरित-ठीक कट और पेस्ट राक्षसों को खोला है। मैं wpf के लिए नया हूँ। मैंने कोड की कोशिश की और दुर्भाग्यवश, सब-मेन्यू माउस-ओवर पर दिखाई नहीं दे रहा है। मैं इसे थोड़ा और जांच करूंगा। –

+0

ओह, मेनू में अपना मेनू इटैम लपेटें। अन्यथा कोई कार्यक्षमता नहीं है। मैंने कोशिश की है और यह काम करता है। – gcores

+0

ओपी में "संपादित करें, संपादित करें" देखें। –

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

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