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

`}

`