2014-10-15 11 views
7

के अंदर मेनू दिखाता है मुझे टेक्स्टबॉक्स के मानक कॉन्टेक्स्टमेनू को अक्षम करने की आवश्यकता है। मैं एक नया WPF परियोजना बना लिया है और निम्नलिखित कहा:WPF ContextMenu = {x: Null} लेकिन अभी भी ContentControl

<Window x:Class="WpfApplication3.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <ContentControl> 
      <ContentControl.ContentTemplate> 
       <DataTemplate> 
        <TextBox ContextMenu="{x:Null}" VerticalAlignment="Top" HorizontalAlignment="Left" Width="50"></TextBox> 
       </DataTemplate> 
      </ContentControl.ContentTemplate> 
     </ContentControl> 
    </Grid> 
</Window> 

लेकिन यह मैं क्या मिलता है:

enter image description here

निम्नलिखित कोड ठीक काम करता है:

<Grid> 
    <TextBox ContextMenu="{x:Null}" VerticalAlignment="Top" HorizontalAlignment="Left" Width="50"></TextBox> 
</Grid> 

क्यों क्या यह हो रहा है?

अद्यतन।

स्वीकार्य उत्तर के अनुसार मैंने टेक्स्टबॉक्स से व्युत्पन्न कक्षा बनाई है ताकि माता-पिता ContextMenu को प्रदर्शित करने में सक्षम हो सकें।

public class TextBoxNoMenu: TextBox 
    { 
     public TextBoxNoMenu() 
     { 
      ContextMenu = null; 
     } 
    } 

उत्तर

3

हो रहा क्यों है: एक बेहतर तरीका यह दृश्यता है परिवर्तित करने के लिए हो सकता है?

यह संपत्ति के कहां/कैसे सेट किया जाता है, इस पर निर्भर करता है कि यह नियंत्रण के व्यवहार का एक दिलचस्प मामला है।

TextBox डिफ़ॉल्ट रूप से अपना स्वयं का संदर्भ मेनू प्रदान करता है। केवल समय यह ऐसा नहीं करेगा जब आप स्थानीय मानContextMenu से null पर स्पष्ट रूप से सेट करेंगे। यह आपके सरल उदाहरण में होता है जहां TextBox सीधे Grid में है।

हालांकि, जब आप एक टेम्पलेट के अंदर एक संपत्ति सेट करते हैं, तो आप वास्तव में स्थानीय मान निर्धारित नहीं कर रहे हैं; आप एक "मूल टेम्पलेट" मान सेट कर रहे हैं। यदि आप DependencyPropertyHelper.GetValueSource() के साथ मान का निरीक्षण करते हैं, तो आप देखेंगे कि बेस मान स्रोत ParentTemplateLocal के बजाय है। इस प्रकार, मेनू अभी भी ओवरराइड हो जाता है।

विभिन्न प्रकार के निर्भरता संपत्ति मूल्य स्रोतों के बारे में अधिक जानकारी के लिए Dependency Property Value Precedence देखें।

@ ओमेगामन का 'छुपा' संदर्भ मेनू निर्दिष्ट करने का सुझाव बहुत अच्छा काम करता है।

+0

मेरा प्रारंभिक लक्ष्य माता-पिता के कॉन्टेक्स्टमेनू को खोलना था। तो, गिरने से वास्तविक समस्या हल नहीं होती है। हालांकि, जब मैंने आपको जवाब दिया तो मैंने टेक्स्टबॉक्स से व्युत्पन्न क्लास टेक्स्टबॉक्स नोमेनू बनाया है और इसके संदर्भ मेनू को हटा दिया है। –

1

ध्यान दें कि या तो टेक्स्ट बॉक्स पर ContextMenu अक्षम mayhave जबकि, अगर यह एक और नियंत्रण में है, तो आप वास्तव में इस तरह के एक आवरण के ContextMenu देखकर हो सकता है। इस प्रकार के व्यवहार को और अधिक विशेष रूप से देखने के लिए Snooping आज़माएं।

ध्यान दें कि पूरे WPF में डिफ़ॉल्ट नियंत्रण टेम्पलेट्स में से कई अपने बच्चों की वस्तुओं को जोड़कर इन मुद्दों को जन्म दे सकते हैं। default template for TextBox देखकर और फिर <ScrollViewer Margin="0" x:Name="PART_ContentHost" /> का उपयोग करता है, तो संभव है कि आप टेक्स्टबॉक्स पर किसी बच्चे ऑब्जेक्ट का ContextMenu देख रहे हों।

+0

उपरोक्त कोड समाधान में मेरे पास सबकुछ है। तो, एकमात्र रैपर ContentControl है। इसके अलावा, अगर मैं ContentControl के ContextMenu को शून्य पर सेट करता हूं तो मुझे वही गलत व्यवहार मिल जाएगा। –

+0

मान लीजिए कि आप टेक्स्टबॉक्स को अपने कुछ बच्चों को जोड़ नहीं रहे हैं। तदनुसार मेरा जवाब अपडेट कर रहा है। – David

1

ऐसा लगता है कि एक्स: नल डिफ़ॉल्ट संदर्भ मेनू को 'बंद नहीं' करता है।

<TextBox.ContextMenu> 
    <ContextMenu Visibility="Collapsed"/> 
</TextBox.ContextMenu> 
0

मुझे एक समान समस्या थी, लेकिन मैं अपने नियंत्रण प्रोग्रामेटिक रूप से उत्पन्न कर रहा था, और मेरा मूल नियंत्रण एक डॉकपनेल है। स्वीकार्य उत्तर के आधार पर, मैंने कोड के पीछे कोड में शून्य मान सेट करने का निर्णय लिया।

 <Grid> 
      <DockPanel> 
       <TextBox Name="txtBox" VerticalAlignment="Top" HorizontalAlignment="Left" Width="50"></TextBox> 
      </DockPanel> 
     </Grid> 

और फिर

  private void Window_Loaded(object sender, RoutedEventArgs e) 
      { 
       txtBox.ContextMenu = null; 
      } 

संपादित करें: मुझे लगा कि यह एक बेतरतीब जवाब की तरह था, पूरी तरह से या सीधे यह सवाल नहीं हल यह करता है के रूप में। मैंने कुछ खुदाई की और यदि आप This Question के उत्तर में मिली विधि को कार्यान्वित करते हैं तो आप कोड-बैक में टेक्स्टबॉक्स पा सकते हैं।

तो, अगर आप इस

 <Grid> 
      <ContentControl> 
       <ContentControl.ContentTemplate> 
       <DataTemplate> 
        <TextBox Name="txtBox" VerticalAlignment="Top" HorizontalAlignment="Left" Width="50"></TextBox> 
       </DataTemplate> 
       </ContentControl.ContentTemplate> 
      </ContentControl> 
     </Grid> 

है तो फिर तुम नाम से अपने पाठ बॉक्स ढूँढने में सक्षम (इस मामले में txtBox) हो सकता है और

   TextBox myTextBox = FindChild<TextBox>(Application.Current.MainWindow, "txtBox"); 

       myTextBox.ContextMenu = null; 

शून्य पर व्यक्तिगत तौर पर मैं संदर्भ मेनू स्थापित करना चाहिए विरासत के साथ एक नई कक्षा बनाने के लिए इसे पसंद करते हैं, लेकिन जो भी आपके लिए काम करता है। यह अभी भी जवाब नहीं देता है "यह क्यों हो रहा है?" लेकिन मुझे लगता है कि स्वीकृत उत्तर उस का अच्छा काम करता है।

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