C# 自定义OpenFileDialog以修改按钮文本
我需要一个文件夹对话框来获取所选文件夹的路径,并希望将多个文件保存到该路径中 我可以使用WindowsApiCodePack 我想将“选择文件夹”按钮中的文本重命名为“保存”,这是我的客户建议的,除了更改它之外,没有其他方法可以满足他们的要求 但是,我可以更改对话框的标题,但不能更改按钮文本 如何修改按钮文本 这应该行得通C# 自定义OpenFileDialog以修改按钮文本,c#,wpf,windows-api-code-pack,C#,Wpf,Windows Api Code Pack,我需要一个文件夹对话框来获取所选文件夹的路径,并希望将多个文件保存到该路径中 我可以使用WindowsApiCodePack 我想将“选择文件夹”按钮中的文本重命名为“保存”,这是我的客户建议的,除了更改它之外,没有其他方法可以满足他们的要求 但是,我可以更改对话框的标题,但不能更改按钮文本 如何修改按钮文本 这应该行得通 var dialog = new CommonOpenFileDialog(); dialog.IsFolderPicker = true; dialog.S
var dialog = new CommonOpenFileDialog();
dialog.IsFolderPicker = true;
dialog.SetOpenButtonText("SAVE TO THIS FOLDER");
如果您使用的是包的版本,那么我不认为有一个简单的开箱即用的解决方案。这是可以做到的,但它需要一些反思来工作(如果有人找到了一个更简单的方法,请分享)
首先,您必须在项目中引用System.Windows.Forms
asembly(如果您还没有)
然后,至少模拟使用它一次,因此方法getReferencedAssemblys()
将返回它(同样,如果仍然使用它,可以跳过此步骤),下面的代码行就足够了:
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);
}
}
说明:
在
WindowsAPICodePack
中,CommonOpenFileDialog
是CommonFileDialog
类的子类。在CommonFileDialog
中,有一个nativeDialog
字段,类型为IFileDialog
(类型IFileDialog
也不是公共的)。您可以使用它来设置按钮的文本。可悲的是,这是私人的。在只调用构造函数之后,它也不会被初始化(但是有些方法会初始化它,因此您必须在开始时检查它是否为null)IFileDialog
有一个内部方法SetOkButtonLabel
。这就是您需要的。您使用的是SaveFileDialog吗?我使用的是CommonOpenFileDialog,FolderPicker为true。您能告诉我这是哪个版本的WindowsApiCodePack吗?我没有这个方法非常感谢你给我这个答案。工作得很有魅力。这真是一个很好的解释
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();