首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使属性仅通过绑定编辑器(组件)进行编辑

使属性仅通过绑定编辑器(组件)进行编辑
EN

Stack Overflow用户
提问于 2022-02-24 09:29:04
回答 1查看 212关注 0票数 2

我有一个PropertyGrid,它有一些类属性绑定到它。每个属性都有一个EditorAttribute,其中我定义了一个自定义类来进行更改。我的愿望是使字符串属性只能通过这个Editor类进行编辑,而不是通过PropertyGrid-textfield进行编辑。

我尝试将它的ReadOnly-attribute更改为true,然后在我的编辑器类中更改这个值,然后在属性设置器-方法中用反射重置它,但是这不能正常工作,因为textfield保持焦点模式,而且我仍然可以进行更改。此外,对我来说,这更像是一个解决办法,而不是一个可接受的解决方案。

是否有一种仅通过EditorComponent-class而不是通过PropertyGrid访问我的属性的设置者的方法?

我的自定义编辑-课程:

代码语言:javascript
复制
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
   using (EditorForm f = new Forms.EditorForm(value.ToString()))
   {
      if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
      {
         PropertyDescriptor descriptor = context.PropertyDescriptor;
         if (descriptor != null)
         {
            ReadOnlyAttribute attribute = descriptor.Attributes[typeof(ReadOnlyAttribute)] as ReadOnlyAttribute;
            if (attribute != null)
            {
               System.Reflection.FieldInfo fieldToChange = attribute.GetType().GetField("isReadOnly", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
               if (fieldToChange != null)
               {
                  fieldToChange.SetValue(attribute, false); // setting it to false
                  value = f.Text;
               }
            }
         }
      }
   }
   return value;
}

在此之后,我用我的setter方法重新修改它:

代码语言:javascript
复制
private string _myText = String.Empty;
[Editor(typeof(...), typeof(UITypeEditor)),
ReadOnly(true)]
public string MyText
{
   get { return _myText; }
   set
   {
      _myText = value;
      PropertyDescriptor descriptor = TypeDescriptor.GetProperties(this)["MyText"];
      if (descriptor != null)
      {
         ReadOnlyAttribute attribute = descriptor.Attributes[typeof(ReadOnlyAttribute)] as ReadOnlyAttribute;
         if (attribute != null)
         {
            System.Reflection.FieldInfo fieldToChange = attribute.GetType().GetField("isReadOnly", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
             if (fieldToChange != null)
                fieldToChange.SetValue(attribute, true); // resetting it to true
         }
      }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-24 10:11:11

您可以添加额外的TypeConverter,这将防止编辑(只需放弃从字符串到destinatino类型的任何转换(甚至目的地也是字符串))。

在此之后,您可以在rutime中通过编辑ReadOnlyAttribute来删除所有有线内容。

代码语言:javascript
复制
public class TestClass
{
    [Editor(typeof(CustomEditor), typeof(UITypeEditor))]
    [TypeConverter(typeof(ReadOnlyConverter))]
    public string MyText { get; set; }
}

public class ReadOnlyConverter : TypeConverter
{
    //just empty class
}

public class CustomEditor : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) 
           => UITypeEditorEditStyle.Modal;

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        var strVal = value as string;
        var svc = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;

        using (var editorForm = new EditorForm())
        {
            editorForm.Value = strVal;

            svc.ShowDialog(editorForm);
            value = editorForm.Value;
        };
        

        return value;
    }
}

此外,您可能需要在EditValue中添加编辑检查,以确保服务可用,输入值是真正的string等等。

您还可以重写ReadOnlyConverter的成员,以显式禁用字符串转换,而不依赖于默认实现。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71249776

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档