Если вы используете эту версию пакета, я не Не думаю, что есть простое готовое решение. Это можно сделать, но для этого требуется немного рефлексии (если кто-то нашел более простой способ, поделитесь).
Во-первых, вы должны сослаться на сборку System.Windows.Forms
в своем проекте (если у вас ее еще нет).
Затем вы имитируете его хотя бы один раз, поэтому метод GetReferencedAssemblies()
возвращает его (опять же, если вы все равно используете его, вы можете пропустить этот шаг), следующей строки кода будет достаточно:
Form f=null;
Теперь это класс с несколькими методами, облегчающими необходимое отражение:
public class MyReflector
{
string myNamespace;
Assembly myAssembly;
public MyReflector(string assemblyName, string namespaceName)
{
myNamespace = namespaceName;
myAssembly = null;
var alist=Assembly.GetExecutingAssembly().GetReferencedAssemblies();
foreach (AssemblyName aN in alist)
{
if (aN.FullName.StartsWith(assemblyName))
{
myAssembly = Assembly.Load(aN);
break;
}
}
}
public Type GetType(string typeName)
{
Type type = null;
string[] names = typeName.Split('.');
if (names.Length > 0)
type = myAssembly.GetType(myNamespace + "." + names[0]);
for (int i = 1; i < names.Length; ++i)
{
type = type.GetNestedType(names[i], BindingFlags.NonPublic);
}
return type;
}
public object Call(Type type, object obj, string func, object[] parameters)
{
MethodInfo methInfo = type.GetMethod(func, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
return methInfo.Invoke(obj, parameters);
}
public object GetField(Type type, object obj, string field)
{
FieldInfo fieldInfo = type.GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
return fieldInfo.GetValue(obj);
}
}
Наконец, код для установки текста кнопки.
CommonOpenFileDialog ofp = new CommonOpenFileDialog();
ofp.IsFolderPicker = true;
// In the CommonFileDialog in WindowsAPICodePack, there is a nativeDialog field of type IFileDialog
// get it first and check if it's not null:
var r1 = new MyReflector("Microsoft.WindowsAPICodePack", "Microsoft.WindowsAPICodePack");
Type typeCommonFileDialog = typeof(CommonFileDialog);
object nativeDialog = r1.GetField(typeCommonFileDialog, ofp, "nativeDialog");
if (nativeDialog == null)
{
// if nativeDialog was null, initialize it:
r1.Call(ofp.GetType(), ofp, "InitializeNativeFileDialog", new object[]{});
nativeDialog = r1.Call(ofp.GetType(), ofp, "GetNativeFileDialog", new object[] { });
}
// call SetOkButtonLabel method on nativeDialog object
var r2 = new MyReflector("System.Windows.Forms", "System.Windows.Forms");
Type typeIFileDialog = r2.GetType("FileDialogNative.IFileDialog");
r2.Call(typeIFileDialog, nativeDialog, "SetOkButtonLabel",new object[] { "Save" });
ofp.ShowDialog();
ОБЪЯСНЕНИЕ:
В WindowsAPICodePack
CommonOpenFileDialog
является подклассом класса CommonFileDialog
. В CommonFileDialog
есть поле nativeDialog
типа IFileDialog
(тип IFileDialog
также не является общедоступным). Вы можете использовать его для установки текста кнопки. К сожалению, это личное. Он также не инициализируется после вызова только конструктора (однако некоторые методы инициализируют его, поэтому вам нужно проверить, является ли он нулевым в начале). IFileDialog
имеет внутренний метод SetOkButtonLabel
. Это то, что вам нужно.
person
Arie
schedule
08.05.2017