FileOpenDialog read-only support · dotnet/wpf@74d617c (original) (raw)
`@@ -173,18 +173,32 @@ public bool Multiselect
`
173
173
`}
`
174
174
`}
`
175
175
``
176
``
`-
// OFN_HIDEREADONLY currently not supported #6346
`
``
176
`+
// Since readonly is now a OK button drop-down menu, it can be changed only by user
`
``
177
`+
// confirming the dialog, so no need to have a live property while dialog is shown.
`
177
178
`///
`
178
179
`/// Gets or sets a value indicating whether the read-only
`
179
180
`/// check box is selected.
`
180
181
`///
`
181
``
`-
public bool ReadOnlyChecked { get; set; }
`
``
182
`+
public bool ReadOnlyChecked
`
``
183
`+
{
`
``
184
`+
get
`
``
185
`+
{
`
``
186
`+
return _isReadonlyChecked;
`
``
187
`+
}
`
``
188
`+
set
`
``
189
`+
{
`
``
190
`+
_isReadonlyChecked = value;
`
``
191
`+
}
`
``
192
`+
}
`
182
193
``
183
``
`-
// OFN_HIDEREADONLY currently not supported #6346
`
184
194
`///
`
185
195
`/// Gets or sets a value indicating whether the dialog
`
186
196
`/// contains a read-only check box.
`
187
197
`///
`
``
198
`+
///
`
``
199
`+
/// Read-only option is shown as a drop-down menu on the dialog's OK button.
`
``
200
`+
/// Any custom button label will be overriden when this property is true.
`
``
201
`+
///
`
188
202
`public bool ShowReadOnly
`
189
203
`{
`
190
204
`get
`
`@@ -193,7 +207,7 @@ public bool ShowReadOnly
`
193
207
`}
`
194
208
`set
`
195
209
`{
`
196
``
`-
_showReadOnly = false;
`
``
210
`+
_showReadOnly = value;
`
197
211
`}
`
198
212
`}
`
199
213
``
`@@ -227,6 +241,53 @@ private protected override IFileDialog CreateDialog()
`
227
241
`return (IFileDialog)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid(CLSID.FileOpenDialog)));
`
228
242
`}
`
229
243
``
``
244
`+
private protected override void PrepareDialog(IFileDialog dialog)
`
``
245
`+
{
`
``
246
`+
base.PrepareDialog(dialog);
`
``
247
+
``
248
`+
// if the OK button already has items, do not interfere with them
`
``
249
`+
// ShowReadOnly/ReadOnlyChecked will be ignored
`
``
250
`+
if (_showReadOnly && OkButton.Items.Count == 0)
`
``
251
`+
{
`
``
252
`+
if (dialog is IFileDialogCustomize customize)
`
``
253
`+
{
`
``
254
`+
OkButton.Items.Lock();
`
``
255
+
``
256
`+
int dropDownID = FileDialogControlBase.NextID();
`
``
257
`+
customize.EnableOpenDropDown(dropDownID);
`
``
258
+
``
259
`+
// these labels have native-style accelerators, so we add them directly
`
``
260
`+
GetCommonDialogLabels(_isReadonlyChecked, out string buttonLabel, out string itemLabel);
`
``
261
`+
// the item IDs are scoped to the control, so we pick 0 = reaad-only not checked, 1 = read-only checked
`
``
262
`+
customize.AddControlItem(dropDownID, _isReadonlyChecked ? 1 : 0, buttonLabel);
`
``
263
`+
customize.AddControlItem(dropDownID, _isReadonlyChecked ? 0 : 1, itemLabel);
`
``
264
+
``
265
`+
_readOnlyID = dropDownID;
`
``
266
`+
}
`
``
267
`+
}
`
``
268
`+
}
`
``
269
+
``
270
`+
private protected override bool TryHandleFileOk(IFileDialog dialog, Stack revertState)
`
``
271
`+
{
`
``
272
`+
revertState.Push(_isReadonlyChecked);
`
``
273
+
``
274
`+
if (_readOnlyID is int id && dialog is IFileDialogCustomize customize)
`
``
275
`+
{
`
``
276
`+
if (customize.GetSelectedControlItem(id, out int itemID).Succeeded)
`
``
277
`+
{
`
``
278
`+
_isReadonlyChecked = itemID != 0;
`
``
279
`+
}
`
``
280
`+
}
`
``
281
+
``
282
`+
return base.TryHandleFileOk(dialog, revertState);
`
``
283
`+
}
`
``
284
+
``
285
`+
private protected override void RevertFileOk(Stack revertState)
`
``
286
`+
{
`
``
287
`+
base.RevertFileOk(revertState);
`
``
288
`+
_isReadonlyChecked = (bool)revertState.Pop();
`
``
289
`+
}
`
``
290
+
230
291
` #endregion Internal Methods
`
231
292
``
232
293
`//---------------------------------------------------
`
`@@ -269,6 +330,23 @@ private void Initialize()
`
269
330
`// the user enters an invalid name, we display a warning in a
`
270
331
`// message box. Implies FOS_PATHMUSTEXIST.
`
271
332
`SetOption(FOS.FILEMUSTEXIST, true);
`
``
333
+
``
334
`+
// reset read-only
`
``
335
`+
_showReadOnly = false;
`
``
336
`+
_isReadonlyChecked = false;
`
``
337
`+
_readOnlyID = null;
`
``
338
`+
}
`
``
339
+
``
340
`+
private static void GetCommonDialogLabels(bool readOnly, out string button, out string item)
`
``
341
`+
{
`
``
342
`+
const uint openID = 0x0172;
`
``
343
`+
const uint openReadOnlyID = 0x01AB;
`
``
344
`+
const uint openForWriteID = 0x01AC;
`
``
345
+
``
346
`+
IntPtr comdlg32 = Standard.NativeMethods.GetModuleHandle(MS.Win32.ExternDll.Comdlg32);
`
``
347
+
``
348
`+
button = Standard.NativeMethods.LoadString(comdlg32, openID);
`
``
349
`+
item = Standard.NativeMethods.LoadString(comdlg32, readOnly ? openForWriteID : openReadOnlyID);
`
272
350
`}
`
273
351
``
274
352
` #endregion Private Methods
`
`@@ -289,6 +367,8 @@ private void Initialize()
`
289
367
`//#region Private Fields
`
290
368
``
291
369
`private bool _showReadOnly = false;
`
``
370
`+
private bool _isReadonlyChecked = false;
`
``
371
`+
private int? _readOnlyID = null;
`
292
372
``
293
373
`//#endregion Private Fields
`
294
374
`}
`