Грязный флаг для пользовательской страницы свойств с VSX

У меня есть собственный пакет, созданный как расширение Visual Studio. Для моего файла проекта я создал две новые страницы настраиваемых свойств. Только эти два отображаются в окне свойств моего проекта. Все работает нормально с флажком Dirty на уровне страницы свойств, что означает, что когда я что-то меняю, единственная вкладка становится грязной, а когда информация сохраняется, она возвращается к негрязной.

Но моя проблема: как только я открываю страницы свойств, основная вкладка представления (где отображается имя проекта) содержит грязный флаг (маленькую звездочку), и мне не удается решить эту проблему. Какое свойство я должен установить, где «не грязный», чтобы вся страница отображалась как «не грязная».

С уважением, Мартин


vsx
person user653427    schedule 02.12.2011    source источник


Ответы (1)


Я помню, что на форумах MSDF (Visual Studio Extensibility) было несколько связанных тем — см. их здесь.

Я уже не уверен, но пример, который я разместил на форумах MSDN (форум VSX) в 'Нужен пример кода для пользовательских страниц свойств' поток работал нормально для меня.

P.S. И вы всегда можете сообщить об ошибке VSX на Microsoft Connent.

См. пример пользовательской страницы свойств ниже, а остальные примеры кода также доступны в ветке MSDN, о которой я упоминал выше.

1   using System; 
2   using System.Diagnostics; 
3   using System.Drawing; 
4   using System.IO; 
5   using System.Runtime.InteropServices; 
6   using System.Text.RegularExpressions; 
7   using System.Windows.Forms; 
8    
9   namespace MyProjectProperties 
10  { 
11      [Guid(Guids.RealCustomPropertyPageGuidString)] 
12      public partial class RealCustomPropertyPage : CustomPropertyPage 
13      { 
14          ...  
15  
16          #region Constructors 
17   
18          public RealCustomPropertyPage() 
19              : base() 
20          { 
21              InitializeComponent(); 
22              Title = ResMgr.GetString(TextKeys.RealCustomPropertyPageCaption); 
23          } 
24  
25          #endregion 
26  
27  
28          #region Overriden Methods 
29   
30          protected override void Initialize() 
31          { 
32              AddComboBoxItems(cboOutputType, OutputTypeManager.Application, OutputTypeManager.Library); 
33              AddComboBoxItems(cboTargetVersion, TargetVersionManager.Flash7, TargetVersionManager.Flash8); 
34   
35              txtAssemblyName.TextChanged += new EventHandler(OnPropertyChanged); 
36              txtDefaultNamespace.TextChanged += new EventHandler(OnPropertyChanged); 
37              txtMainClass.TextChanged += new EventHandler(OnPropertyChanged); 
38              txtInputSwfLocation.TextChanged += new EventHandler(OnRefreshControlStateChanged); 
39              txtOutputPath.TextChanged += new EventHandler(OnPropertyChanged); 
40              txtFrameParameter.TextChanged += new EventHandler(OnPropertyChanged); 
41              txtFrameRate.TextChanged += new EventHandler(OnPropertyChanged); 
42              txtWidth.TextChanged += new EventHandler(OnPropertyChanged); 
43              txtHeight.TextChanged += new EventHandler(OnPropertyChanged); 
44              txtColorPreview.TextChanged += new EventHandler(OnColorPreviewChanged); 
45              txtAdditionalParams.TextChanged += new EventHandler(OnPropertyChanged); 
46   
47              cboOutputType.SelectedIndexChanged += new EventHandler(OnRefreshControlStateChanged); 
48              cboTargetVersion.SelectedIndexChanged += new EventHandler(OnPropertyChanged); 
49   
50              chkInputSwfLocation.CheckedChanged += new EventHandler(OnRefreshControlStateChanged); 
51              chkKeepParameter.CheckedChanged += new EventHandler(OnPropertyChanged); 
52              chkFrameParameter.CheckedChanged += new EventHandler(OnPropertyChanged); 
53              chkUsePrecompiledMxClasses.CheckedChanged += new EventHandler(OnPropertyChanged); 
54              chkUseTypeInference.CheckedChanged += new EventHandler(OnPropertyChanged); 
55              chkUseStrictCompilation.CheckedChanged += new EventHandler(OnPropertyChanged); 
56   
57              btnBrowseInputSwf.Click += new EventHandler(OnBrowseInputSwfClicked); 
58              btnBrowseMainClass.Click += new EventHandler(OnBrowseMainClassClicked); 
59              btnSelectBackgroundColor.Click += new EventHandler(OnSelectBackgroundColorClicked); 
60              btnSetOutputPath.Click += new EventHandler(OnBrowseOutputPathClicked); 
61   
62              RefreshControlState(); 
63          } 
64   
65          protected override void FillProperties() 
66          { 
67              Fill(txtAssemblyName, Property.AssemblyName); 
68              Fill(txtDefaultNamespace, Property.DefaultNamespace); 
69              Fill(txtMainClass, Property.MainClass); 
70              Fill(txtOutputPath, Property.AsOutputPath); 
71              Fill(txtInputSwfLocation, Property.InputSwfLocation); 
72              Fill(txtFrameParameter, Property.FrameParameter); 
73              Fill(txtFrameRate, Property.FrameRate); 
74              Fill(txtWidth, Property.Width); 
75              Fill(txtHeight, Property.Height); 
76              Fill(txtAdditionalParams, Property.AdditionalParams); 
77   
78              Fill(lblColorPreview, Property.BackgroundColor); 
79   
80              Fill(cboTargetVersion, Property.TargetVersion); 
81              Fill(cboOutputType, Property.OutputType); 
82   
83              Fill(chkInputSwfLocation, Property.UseInputSwf); 
84              Fill(chkKeepParameter, Property.KeepInputClasses); 
85              Fill(chkFrameParameter, Property.UseFrameParameter); 
86              Fill(chkUsePrecompiledMxClasses, Property.UsePrecompiledMxClasses); 
87              Fill(chkUseTypeInference, Property.UseTypeInference); 
88              Fill(chkUseStrictCompilation, Property.UseStrictCompilation); 
89          } 
90   
91          protected override bool CheckInput() 
92          { 
93              bool valid = true; 
94   
95              valid &= CheckSwfInputFileValid(); 
96              valid &= CheckFrameRateValid(); 
97              valid &= CheckWidthValid(); 
98              valid &= CheckHeightValid(); 
99              valid &= CheckFrameValid(); 
100             valid &= CheckOutputPathValid(); 
101  
102             return valid; 
103         } 
104  
105         protected override void ApplyChanges() 
106         { 
107             bool needReParse = GetComboValue(cboTargetVersion) != GetProperty(Property.TargetVersion); 
108  
109             Apply(txtAssemblyName, Property.AssemblyName); 
110             Apply(txtDefaultNamespace, Property.DefaultNamespace); 
111             Apply(txtMainClass, Property.MainClass); 
112             Apply(txtOutputPath, Property.AsOutputPath); 
113             Apply(txtInputSwfLocation, Property.InputSwfLocation); 
114             Apply(txtFrameParameter, Property.FrameParameter); 
115             Apply(txtFrameRate, Property.FrameRate); 
116             Apply(txtWidth, Property.Width); 
117             Apply(txtHeight, Property.Height); 
118             Apply(txtAdditionalParams, Property.AdditionalParams); 
119  
120             Apply(lblColorPreview, Property.BackgroundColor); 
121  
122             Apply(cboOutputType, Property.OutputType); 
123             Apply(cboTargetVersion, Property.TargetVersion); 
124  
125             Apply(chkInputSwfLocation, Property.UseInputSwf); 
126             Apply(chkKeepParameter, Property.KeepInputClasses); 
127             Apply(chkFrameParameter, Property.UseFrameParameter); 
128             Apply(chkUsePrecompiledMxClasses, Property.UsePrecompiledMxClasses); 
129             Apply(chkUseTypeInference, Property.UseTypeInference); 
130             Apply(chkUseStrictCompilation, Property.UseStrictCompilation); 
131  
132             // Re-parse with new target type applied 
133             if (needReParse && SettingManager.EnableIntelliSense && NeutronKeeper.Registered) 
134             { 
135                 string property = GetProperty(Property.TargetVersion); 
136                 string directory = TargetVersionManager.DefineDirectory(property); 
137                 Debug.Assert(Directory.Exists(directory)); 
138  
139                 SymbolTable cache = ((AsProjectNode)ProjectMgr).GetCache(); 
140                 cache.ParseSourcesFromDirectory(directory, true, true); 
141             } 
142         } 
143 
144         #endregion 
145 
146 
147         #region Private Methods 
148  
149         private void OnPropertyChanged(object sender, EventArgs e) 
150         { 
151             MarkPageChanged(); 
152         } 
153  
154         private void OnRefreshControlStateChanged(object sender, EventArgs e) 
155         { 
156             RefreshControlState(); 
157             MarkPageChanged(); 
158         } 
159  
160         private void OnBrowseOutputPathClicked(object sender, EventArgs e) 
161         { 
162             FolderBrowserDialog dialog = new FolderBrowserDialog(); 
163  
164             string projectDir = GetProperty(Property.MSBuildProjectDirectory); 
165             PropertyHelper.SetPaths(dialog, projectDir, txtOutputPath.Text); 
166  
167             if (DialogResult.OK == dialog.ShowDialog()) 
168             { 
169                 txtOutputPath.Text = PathHelper.MakeRelative(projectDir, dialog.SelectedPath); 
170                 MarkPageChanged(); 
171             } 
172         } 
173  
174         private void OnSelectBackgroundColorClicked(object sender, EventArgs e) 
175         { 
176             ColorDialog dialog = new ColorDialog(); 
177             dialog.Color = lblColorPreview.BackColor; 
178             if (DialogResult.OK == dialog.ShowDialog()) 
179             { 
180                 SetColorPreview(lblColorPreview, dialog.Color); 
181                 MarkPageChanged(); 
182             } 
183         } 
184  
185         private void OnBrowseMainClassClicked(object sender, EventArgs e) 
186         { 
187             OpenFileDialog dialog = new OpenFileDialog(); 
188             dialog.Title = ResMgr.GetString(TextKeys.BrowseMainClassTitle); 
189             dialog.Filter = ResMgr.GetString(TextKeys.BrowseMainClassFilter); 
190  
191             string projectDir = GetProperty(Property.MSBuildProjectDirectory); 
192             PropertyHelper.SetPaths(dialog, projectDir, txtMainClass.Text); 
193  
194             if (DialogResult.OK == dialog.ShowDialog()) 
195             { 
196                 txtMainClass.Text = PathHelper.MakeRelative(projectDir, dialog.FileName); 
197                 OnPropertyChanged(sender, e); 
198             } 
199         } 
200  
201         private void OnBrowseInputSwfClicked(object sender, EventArgs e) 
202         { 
203             OpenFileDialog dialog = new OpenFileDialog(); 
204             dialog.Title = ResMgr.GetString(TextKeys.BrowseInputSwfTitle); 
205             dialog.Filter = ResMgr.GetString(TextKeys.BrowseInputSwfFilter); 
206  
207             string projectDir = GetProperty(Property.MSBuildProjectDirectory); 
208             PropertyHelper.SetPaths(dialog, projectDir, txtInputSwfLocation.Text); 
209  
210             if (DialogResult.OK == dialog.ShowDialog()) 
211             { 
212                 txtInputSwfLocation.Text = PathHelper.MakeRelative(projectDir, dialog.FileName); 
213                 OnPropertyChanged(sender, e); 
214             } 
215         } 
216  
217         private void OnColorPreviewChanged(object sender, EventArgs e) 
218         { 
219             Match match = _hexColorRegex.Match(txtColorPreview.Text.Trim()); 
220             if (match.Success) 
221             { 
222                 SetColorPreview(lblColorPreview, HexStringToColor(match.Captures[0].Value)); 
223             } 
224         } 
225  
226         private void RefreshControlState() 
227         { 
228             // Input swiff file block related 
229             bool allowToSelectInputSwf = chkInputSwfLocation.Checked; 
230             bool isInputSwfHasValue = txtInputSwfLocation.Text.Trim().Length > 0; 
231  
232             txtInputSwfLocation.Enabled = allowToSelectInputSwf; 
233             btnBrowseInputSwf.Enabled = allowToSelectInputSwf; 
234             chkKeepParameter.Enabled = allowToSelectInputSwf && isInputSwfHasValue; 
235             chkUsePrecompiledMxClasses.Enabled = allowToSelectInputSwf && isInputSwfHasValue; 
236  
237             // Application settings group related 
238             gbxApplicationSettings.Enabled = (GetComboValue(cboOutputType) == OutputTypeManager.Application); 
239         } 
240  
241         private bool CheckFrameRateValid() 
242         { 
243             return IsPositiveInteger(txtFrameRate.Text, "Invalid Frame Rate value."); 
244         } 
245  
246         private bool CheckFrameValid() 
247         { 
248             return IsPositiveInteger(txtFrameParameter.Text, "Invalid Target Frame value."); 
249         } 
250  
251         private bool CheckHeightValid() 
252         { 
253             return IsPositiveInteger(txtHeight.Text, "Invalid Height value."); 
254         } 
255  
256         private bool CheckWidthValid() 
257         { 
258             return IsPositiveInteger(txtWidth.Text, "Invalid Width value."); 
259         } 
260  
261         private bool IsPositiveInteger(string toParse, string errorMessage) 
262         { 
263             try 
264             { 
265                 uint.Parse(toParse); 
266             } 
267             catch 
268             { 
269                 _logger.Info(errorMessage); 
270                 MessageBox.Show(errorMessage); 
271                 return false; 
272             } 
273             return true; 
274         } 
275  
276         private bool CheckSwfInputFileValid() 
277         { 
278             ...  
279         } 
280  
281         private bool CheckOutputPathValid() 
282         { 
283             ...  
284         } 
285  
286         private void Fill(Label label, Property property) 
287         { 
288             string backgroundColor = ProjectMgr.GetProjectProperty(property.ToString(), true); 
289             SetColorPreview(label, HexStringToColor(backgroundColor)); 
290         } 
291  
292         private void SetColorPreview(Label label, Color color) 
293         { 
294             txtColorPreview.Text = label.Text = ColorTranslator.ToHtml(color); 
295             label.BackColor = color; 
296         } 
297  
298         private void Apply(Label acceptor, Property property) 
299         { 
300             string hexString = ColorToHexString(acceptor.BackColor); 
301             ProjectMgr.SetProjectProperty(property.ToString(), hexString); 
302         } 
303  
304         private string FilterDirectoryPath(string dirPath) 
305         { 
306             if (dirPath.Split(Path.GetInvalidPathChars()).Length > 1) 
307             { 
308                 dirPath = dirPath.Trim(); 
309                 foreach(char invalidCharacter in Path.GetInvalidPathChars()) 
310                 { 
311                     dirPath = dirPath.Replace(invalidCharacter.ToString(), string.Empty); 
312                 } 
313             } 
314             return dirPath; 
315         } 
316 
317 
318         #region HEX <-> Color convertions 
319  
320         ... skipped ... 
321 
322         #endregion 
323 
324 
325         #endregion 
326     } 
327 } 
person Dmitry Pavlov    schedule 21.02.2012