将参数添加到基于Itypeeditor的WPF自定义控件中?[英] Add a parameter to a WPF custom control based on ITypeEditor?

本文是小编为大家收集整理的关于将参数添加到基于Itypeeditor的WPF自定义控件中?的处理方法,想解了将参数添加到基于Itypeeditor的WPF自定义控件中?的问题怎么解决?将参数添加到基于Itypeeditor的WPF自定义控件中?问题的解决办法?将参数添加到基于Itypeeditor的WPF自定义控件中?问题的解决方案?那么可以参考本文帮助大家快速定位并解决问题,译文如有不准确的地方,大家可以切到English参考源文内容。

问题描述

C#,WPF,xceed PropertyGrid.我正在使用自定义控件在A PropertyGrid中提供浏览按钮.用例中有很多变化(例如,最明显地浏览文件夹VS文件),为这些情况创建单独的编辑器不会很干燥.理想情况下,我想引入一个参数,但我不确定如何将其传递给控件.是否有一个相当简单的方法来实现这一目标?

对我来说,最优雅的解决方案似乎能够将其传递给枚举(对于'模式'),但是如果我可以将编辑器附加到(即在以下示例中ProjectFolder)的属性,则这也将有目的.

public partial class PropertyGridFilePicker : ITypeEditor
{
    string rtn = "";
    public PropertyGridFilePicker()
    {
        InitializeComponent();
    }

    public string Value
    {
        get { return (string)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Value.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(string), typeof(PropertyGridFilePicker), new PropertyMetadata(null));

    public FrameworkElement ResolveEditor(PropertyItem propertyItem)
    {
        Binding binding = new Binding("Value");
        binding.Source = propertyItem;
        binding.Mode = propertyItem.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay;
        BindingOperations.SetBinding(this, ValueProperty, binding);
        return this;
    }

    private void PickFileButton_Click(object sender, RoutedEventArgs e)
    {
        OpenFileDialog fd = new OpenFileDialog();
        if (fd.ShowDialog() == true && fd.CheckFileExists)
        {
            Value = fd.FileName;
            Value = rtn;
        }
    }
}

它是这样使用的:

[Editor(typeof(MyControls.PropertyGridFilePicker), typeof(MyControls.PropertyGridFilePicker))]
public string ProjectFolder { get; set; } = "";

推荐答案

在此处给出的答案:

可能可以致电WPF类型编辑器的构造函数(从Itypeeditor继承)?

虽然被发布为另一个问题,但这与同一问题有关.我要求澄清此处给出的另一个答案中提出的依赖注入解决方案,因为我不明白这是如何工作的.看来不会.

其他推荐答案

我会说最优雅的方式是IOC.依赖注入超级正常的实例.

因为以后您希望介绍另一种类型的文件夹处理或编辑器,您只是注入新的混凝土而不是设计框架工作实例.您要做的就是扩展Frameworkelement的现有功能.

我不会为您编写您的代码,但是我会更好地解释自己.

ioc是控制的反转,我个人认为它是坚实原则的最后一步的一部分.依赖性反转.

您必须通过抽象.老实说,我建议使用界面,而不是抽象,而不是摘要真正遵循依赖注入模式的精神.但是嗯,我不明白为什么不.

这个概念是,解决编辑器应该在一个实例中完成,该实例是在您的Frameworkelement类之外创建的,然后传递到propertyGridFilePicker的构造函数中.

您还可以从坚实的原则中获取页面,并使用单一的责任模式,这意味着班级只能承担1个责任.您可能会争辩说,基于参数det解决类型编辑器,否则不影响该类,这是违反此原则的行为.

我会将其全部依赖于接口,并传递可能从控制器的所需输入,转到包含编辑人员解决逻辑的具体实现,甚至可能是您的Value属性和源属性的解决逻辑.

.

这将允许您将2个冻结的实例传递到一个呼吸中,然后将其传递到propertyGridFilePicker类,并从" IResolveeditor"的contrete实例中创建它的绑定等,或者您想调用界面的任何内容,并在这种情况下配置" PropertyGridFilePicker"类型的特定conctrete模型.

这对您有意义吗?

本文地址:https://www.itbaoku.cn/post/2352199.html

问题描述

C#, WPF, xceed PropertyGrid. I am using a custom control to provide a browse button in a PropertyGrid. There are variations in use case (e.g. most obviously browsing for a folder vs file), and creating separate editors for those cases would not be very DRY. Ideally I would like to introduce a parameter, but I am not sure how to pass that to the control. Is there a reasonably simple way to achieve this?

To me the most elegant solution would seem to be able to pass it an enum (for 'mode'), but if I could get the property that the editor is attached to (i.e. ProjectFolder in the following example) then that would also serve the purpose.

public partial class PropertyGridFilePicker : ITypeEditor
{
    string rtn = "";
    public PropertyGridFilePicker()
    {
        InitializeComponent();
    }

    public string Value
    {
        get { return (string)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Value.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(string), typeof(PropertyGridFilePicker), new PropertyMetadata(null));

    public FrameworkElement ResolveEditor(PropertyItem propertyItem)
    {
        Binding binding = new Binding("Value");
        binding.Source = propertyItem;
        binding.Mode = propertyItem.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay;
        BindingOperations.SetBinding(this, ValueProperty, binding);
        return this;
    }

    private void PickFileButton_Click(object sender, RoutedEventArgs e)
    {
        OpenFileDialog fd = new OpenFileDialog();
        if (fd.ShowDialog() == true && fd.CheckFileExists)
        {
            Value = fd.FileName;
            Value = rtn;
        }
    }
}

It is used like this:

[Editor(typeof(MyControls.PropertyGridFilePicker), typeof(MyControls.PropertyGridFilePicker))]
public string ProjectFolder { get; set; } = "";

推荐答案

Answer given here:

Possible to call the constructor of a WPF type editor (inheriting from ITypeEditor)?

Although posted as a different question, this related to the same problem. I asked for clarification on the Dependency Injection solution proposed in the other answer given here since I didn't understand how this could work. And it seems it wouldn't.

其他推荐答案

I would say the most elegant way is by IoC. Dependency injection superceeds normal instancing.

Because if you later wish to introduce another type of folder handling or editor you just inject a new concrete instead of designing a instance of FrameworkElement. All you have to do is extend the existing functionality of FrameworkElement.

I won't write your code for you, but I will explain myself a bit better.

IoC is inversion of control, I personally, consider it part of the last step of the SOLID principles. Dependency Inversion.

You have to pass an abstraction. I recommend using an interface, instead of an abstract, to be honest, I don't think abstracts are really following the spirit of the dependency injection pattern. But meh, I don't see why not.

The concept is, that resolving the editor for example, should be done in an instance, that was created outside your FrameWorkElement class, and then passed into the constructor of your PropertyGridFilePicker.

You could also take a page from the SOLID principles and use the single responsibility pattern, meaning that a class should only ever have 1 responsibility. And you could argue that resolving the type editor based on a parameter det that otherwise doesn't effect the class, is a violation of this principle.

I would make it all interface dependent and pass in the required input likely from a controller, to concrete implementations that contain the resolving logic for editors, perhaps even the resolving logic for your value property and your source property.

This would allow you to pass 2 contrete instance into a single contrete that you then pass to the PropertyGridFilePicker class, and it creates it's bindings etc, from the contrete instance, of your "IResolveEditor" or whatever you want to call the interface, and configures the specific conctrete model of type "PropertyGridFilePicker", in this instance.

Does this make sense to you?

查看更多