के साथ अजीब बग हमने हाल ही में वीएस 2012 में अपग्रेड किया है जिसके साथ .NET Framework 4.5 में अपग्रेड किया गया है। यह WinForms मेनूस्ट्रिप नियंत्रण के संबंध में एक अजीब और अजीब बग पेश करता है। 4.5 वें इंस्टॉलर के रूप में .NET Framework 4.0 को लक्षित करने वाले अनुप्रयोगों में वही बग भी होता है जो स्पष्ट रूप से 4.0 के हिस्सों को भी अपडेट करता है। इसलिए, फ्रेमवर्क अपग्रेड के कारण अब पूरी तरह से काम कर रहे कोड पैटर्न को तोड़ दिया गया है।.NET 4.0/4.5 WinForms मेनूस्ट्रिप स्टीलिंग फोकस
समस्या का वर्णन:
मैं एक MenuStrip के साथ एक Form1 है। ड्रॉप डाउन आइटमों में से एक के लिए, ईवेंट हैंडलर एक और फॉर्म 2 खोलता है (असफल रूप से एक बच्चा नहीं, सिर्फ एक और फॉर्म)। यदि उपयोगकर्ता नए फॉर्म 2 या उसके बाल नियंत्रण में से एक में राइट-क्लिक करता है और यह ContextMenuStrip का एक शो() ट्रिगर करता है, तो मूल फॉर्म 1 फिर से अग्रभूमि में पॉप हो जाता है।
यह फॉर्म 2 में पिछले सभी यूआई कार्यों से स्वतंत्र होता है। कोई भी आकार बदल सकता है, स्थानांतरित कर सकता है, छोटा कर सकता है, फॉर्म 2 को अधिकतम कर सकता है, नियंत्रणों के बीच स्विच कर सकता है, टेक्स्ट दर्ज कर सकता है। किसी भी तरह फॉर्म 1 के मेनूस्ट्रिप को याद रखना प्रतीत होता है कि यह फॉर्म 2 खोलने और पहले राइट-क्लिक पर फ्रेस फोकस करने का कारण बनता है।
मैं विभिन्न दृष्टिकोणों के साथ प्रयोग कर रहा था लेकिन अब तक कोई कामकाज नहीं ढूंढ पाया। नक्षत्र असामान्य नहीं है और आसपास के WinForms अनुप्रयोगों को प्रभावित कर सकता है। इसलिए मैंने इसे यहां पोस्ट करने का फैसला किया क्योंकि व्यवहार्य समाधान सामान्य रुचि का हो सकता है। अगर कोई कामकाज जानता है या कम से कम मेरे लिए कुछ सुराग है तो मुझे बहुत खुशी होगी।
मैं निम्नलिखित कोड में इसका सार वितरित करने में सक्षम था। इसे .NET 4.5 के साथ किसी भी मशीन पर पुन: उत्पन्न किया जाना चाहिए और यह 4.0 और 4.5 प्रत्येक को लक्षित करते समय होता है - लेकिन 3.5 या उससे कम नहीं।
using System;
using System.Windows.Forms;
namespace RightClickProblem {
static class Program {
[STAThread]
static void Main() {
// Construct a MenuStrip with one item "Menu" with one dropdown-item "Popup"
var mainMenu = new MenuStrip();
var mainItem = new ToolStripMenuItem("Menu");
mainItem.DropDownItems.Add(new ToolStripMenuItem("Popup", null, Popup));
mainMenu.Items.Add(mainItem);
// Create form with MenuStrip and Show
var form1 = new Form();
form1.Controls.Add(mainMenu);
Application.Run(form1);
}
private static void Popup(object sender, EventArgs e) {
// Create a form with a right click handler and show
var form2 = new Form();
var contextMenu = new ContextMenuStrip();
contextMenu.Items.Add("Just an item...");
form2.ContextMenuStrip = contextMenu;
form2.Show();
// Problem: contextMenu.Show() will give focus to form1
}
}
}
संपादित करें: मैं कुछ समय बिताया .नेट फ्रेमवर्क स्रोत कोड के माध्यम से कदम और मूल कारण पाया System.Windows.Forms.ToolStripManager में बहुत संभव है किया जाना है। वहां, माइक्रोसॉफ्ट विंडो सक्रियण को ट्रैक करने के लिए एक संदेश फ़िल्टर का उपयोग कर रहा है जिसे मेनूस्ट्रिप के लिए गलत तरीके से कार्यान्वित किया गया है।
इसी दौरान मैंने यह भी पाया कि माइक्रोसॉफ्ट ने पहले से ही इस समस्या को हॉटफिक्स में संबोधित किया है (http://support.microsoft.com/kb/2769674 देखें) और उम्मीद है कि यह .NET Framework 4.5 के भविष्य के अपडेट में अपना रास्ता खोजेगा।
दुर्भाग्य से सभी क्लाइंट मशीनों पर इस हॉटफिक्स को लागू करना मुश्किल है। इसलिए एक व्यावहारिक कामकाज अभी भी बहुत सराहना की जाएगी। मैं अपने आप को अब तक असमर्थ एक व्यावहारिक समाधान खोजने के लिए किया गया है ...
संपादित करें # 2: मूल KB संख्या Win8 के लिए है, लेकिन KB 2756203. तहत Win7 & Vista के लिए समान Hotfix किसी के लिए इसका इस्तेमाल कर सकते हैं है , यहां डाउनलोड करने के लिए हॉटफिक्स मिला: http://thehotfixshare.net/board/index.php?autocom=downloads&showfile=15569। हमने इसका परीक्षण किया और यह वास्तव में समस्या को हल करता है। अगर हमें जल्द ही कोई कामकाज नहीं मिल रहा है, तो हम हॉटफिक्स के साथ जाएंगे।
संपादित # 3: spajce
जाहिर शो को फोन करके प्रस्तावित स्वीकार किए जाते हैं समाधान के लिए टिप्पणियां() पर किसी भी ContextMenu फोकस पर अपना दावा के बारे में भूल करने के लिए मूल MenuStrip को समझाने होगा। यह एक तरह से किया जा सकता है ताकि डमी ContextMenu स्क्रीन पर भी नहीं दिखाया जा सकता है।
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
using (var dummyMenu = new ContextMenuStrip()) {
dummyMenu.Items.Add(new ToolStripMenuItem());
dummyMenu.Show(Point.Empty);
}
}
}
इसलिए हर फार्म खुलती ToolStripMenu प्रणाली के भ्रष्ट राज्य को साफ: मैं सबसे छोटी और ज्यादा लागू करने के लिए आसान तरीका किसी भी फार्म के निर्माता में निम्न स्निपेट डाल पाया। कोई भी इस कोड को फॉर्महेल्पर जैसी स्थैतिक विधि में रख सकता है।FixToolStripState() या इसे टेम्पलेट के ऑनक्रेट कंट्रोल (...) में डाल दें और उस से सभी फॉर्मों का वारिस करें (वैसे भी हम क्या सौभाग्य से करते हैं)।
बहुत अच्छा repro। मुझे गंभीरता से संदेह है कि आपको एक जवाब मिलेगा, टूलस्ट्रिप कक्षाएं एक प्रमुख दर्द हैं। मैं इसे माइक्रोसॉफ्ट सपोर्ट में ले जाऊंगा। –
हॉटफिक्स विवरण को देखते हुए, यह बिल्कुल विपरीत समस्या है। यह संदेश फ़िल्टर को पर्याप्त तेज़ी से नहीं हटाता है। समस्या देखने के लिए बस फॉर्म पर बायाँ-क्लिक करें। टूलस्ट्रिप मैनेजर में कोड है जो फ़िल्टर को हटाने के लिए माना जाता है जब दूसरी विंडो सक्रिय होती है, ऐसा नहीं हो रहा है। उम्मीद है कि यह हॉटफिक्स इसे जल्द ही एक अद्यतन में लाता है, यह एक बहुत ही सकल बग है। –
मूल कारणों से निपटना मुश्किल है क्योंकि विभिन्न योगदान भागों को स्रोत कोड में बहुत वितरित किया जाता है। चूंकि मैंने फ्रेमवर्क कोड को ठीक करने का कोई तरीका नहीं देखा है, इसलिए मैंने कुछ बिंदु पर रुक दिया। मुझे आश्चर्य हुआ कि अंतर्निहित कार्यान्वयन गंदा है (मेरी राय में) लेकिन मुझे आश्चर्य नहीं है कि यह कोड ऐसी बगों के लिए बहुत प्रवण है। – markus987