CollectionEditorPicker 的 Telerik RadPropertyGrid 内容 [英] Telerik RadPropertyGrid Content of CollectionEditorPicker

查看:28
本文介绍了CollectionEditorPicker 的 Telerik RadPropertyGrid 内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如主题所暗示的那样,我不想修改 CollectionEditorPicker 的内容.此控件用于打开嵌套属性列表的浮动窗口.不幸的是,RadPropertyGrid 不显示有关字段中集合的任何信息.我怎样才能在那里设置一些值?例如,像单击此处打开集合"或xx 项"或项 1、项 2、项 3..."之类的占位符,因此请查看有关该字段的一些预览或信息.

as the topic suggests I wan't to modify the Content of the CollectionEditorPicker. This control is used to open the floating Window for the List of nested Properties. Unfortunally the RadPropertyGrid don't show any Information about the collection in the Field. How can I set some value in there? For example a placeholder like "Click here to open the collection" or "xx Items" or "Item 1, Item 2, Item 3..." so see some preview or Information about the field.

我已经用模板选择器试过了,但如果我这样做了,打开的弹出窗口就不能再调整大小了.它还丢失了默认 CollectionEditorPicker 中的一些信息.你能帮我吗?

I've tried it with a template Selector, but if I'm doing so, the opened Popup is not resizable anymore. Also it looses some Information which are in the default CollectionEditorPicker. Can you help me?

下面是一个最小的工作示例.

Below a minimal working Example.

XAML:

<Window x:Class="TelerikPropertyGridTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
        xmlns:model="clr-namespace:TelerikPropertyGridTest.Model"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.Resources>
            <model:TemplateSelector x:Key="RadPropertyListTemplateSelector">
                <!-- Not Working -->
                <model:TemplateSelector.CollectionsDataTemplate>
                        <DataTemplate>
                           <telerik:RadDropDownButton Content="Test">
                               <telerik:RadDropDownButton.DropDownContent>
                                   <telerik:CollectionEditor telerik:AutoBindBehavior.UpdateBindingOnElementLoaded="Source"
                                                             ></telerik:CollectionEditor>
                               </telerik:RadDropDownButton.DropDownContent>
                           </telerik:RadDropDownButton>
                        </DataTemplate>
                </model:TemplateSelector.CollectionsDataTemplate>
                <model:TemplateSelector.FloatNumberTemplate>
                    <DataTemplate>
                        <telerik:RadNumericUpDown telerik:AutoBindBehavior.UpdateBindingOnElementLoaded="Value" />
                    </DataTemplate>
                </model:TemplateSelector.FloatNumberTemplate>
                <model:TemplateSelector.IntNumberTemplate>
                    <DataTemplate>
                        <telerik:RadNumericUpDown telerik:AutoBindBehavior.UpdateBindingOnElementLoaded="Value"
                                                  NumberDecimalDigits="0" />
                    </DataTemplate>
                </model:TemplateSelector.IntNumberTemplate>
            </model:TemplateSelector>
        </Grid.Resources>
        <telerik:RadPropertyGrid Item="{Binding ObjectToBind}" 
                                 AutoGeneratingPropertyDefinition="RadPropertyGrid_OnAutoGeneratingPropertyDefinition"
                                 EditorTemplateSelector="{StaticResource RadPropertyListTemplateSelector}">
        </telerik:RadPropertyGrid>
    </Grid>
</Window>

ViewModel(生成随机对象进行测试)

The ViewModel (generates a Random Object for testing)

public class MainWindowViewModel : BindableBase
{

    private readonly Random _random = new Random();

    private IExampleInterface _objectToBind;

    public MainWindowViewModel()
    {
        this.ObjectToBind = new ExampleImplementation
                            {
                                SomeBooleanValue = this._random.Next() % 2 == 1,
                                SomeDateValue = this.RandomDay(),
                                SomeIntValue = this._random.Next(),
                                SomeString = Guid.NewGuid().ToString(),
                                SubClasses = new List<IExampleInterface>
                                             {
                                                 new ExampleImplementation
                                                 {
                                                     SomeBooleanValue = this._random.Next() % 2 == 1,
                                                     SomeDateValue = this.RandomDay(),
                                                     SomeIntValue = this._random.Next(),
                                                     SomeString = Guid.NewGuid().ToString(),
                                                     SubClasses = new List<IExampleInterface>
                                                                  {
                                                                      new ExampleImplementation
                                                                      {
                                                                          SomeBooleanValue =
                                                                              this._random.Next() % 2 == 1,
                                                                          SomeDateValue = this.RandomDay(),
                                                                          SomeIntValue = this._random.Next(),
                                                                          SomeString = Guid.NewGuid().ToString()
                                                                      }
                                                                  }
                                                 }
                                             }
                            };
    }

    public IExampleInterface ObjectToBind
    {
        get { return this._objectToBind; }
        set
        {
            if (this._objectToBind != value)
            {
                this._objectToBind = value;
                this.OnPropertyChanged("ObjectToBind");
            }
        }
    }

    private DateTime RandomDay()
    {
        var start = new DateTime(1995, 1, 1);
        var range = (DateTime.Today - start).Days;
        return start.AddDays(this._random.Next(range));
    }

}

IExampleInterface(稍后应该在真正的接口上):

The IExampleInterface (should be later on a real Interface):

public interface IExampleInterface
{
    string SomeString { get; set; }
    int SomeIntValue { get; set; }
    double SomeDouble { get; set; }
    IList<IExampleInterface> SubClasses { get; set; }
    IList<IExampleInterface> SubClasses2 { get; set; }
    bool SomeBooleanValue { get; set; }
    DateTime SomeDateValue { get; set; }
    SomeEnum SomeEnumValue { get; set; }
}

ExampleImplementation(稍后应该有一个带有附加属性的真实实现).

The ExampleImplementation (should have later on a Real Implementation with additional Properties).

public class ExampleImplementation : BindableBase, IExampleInterface
{

    private bool _someBooleanValue;
    private DateTime _someDateValue;
    private double _someDouble;
    private SomeEnum _someEnumValue;
    private int _someIntValue;
    private string _someString;
    private ObservableCollection<IExampleInterface> _subClasses;

    private ObservableCollection<IExampleInterface> _subClasses2;

    public bool SomeBooleanValue
    {
        get { return this._someBooleanValue; }
        set
        {
            if (this._someBooleanValue != value)
            {
                this._someBooleanValue = value;
                this.OnPropertyChanged("SomeBooleanValue");
            }
        }
    }

    public DateTime SomeDateValue
    {
        get { return this._someDateValue; }
        set
        {
            if (this._someDateValue != value)
            {
                this._someDateValue = value;
                this.OnPropertyChanged("SomeDateValue");
            }
        }
    }

    public double SomeDouble
    {
        get { return this._someDouble; }
        set
        {
            if (Math.Abs(this._someDouble - value) > 0.01)
            {
                this._someDouble = value;
                this.OnPropertyChanged("SomeDouble");
            }
        }
    }

    public SomeEnum SomeEnumValue
    {
        get { return this._someEnumValue; }
        set
        {
            if (this._someEnumValue != value)
            {
                this._someEnumValue = value;
                this.OnPropertyChanged("SomeEnumValue");
            }
        }
    }

    public int SomeIntValue
    {
        get { return this._someIntValue; }
        set
        {
            if (this._someIntValue != value)
            {
                this._someIntValue = value;
                this.OnPropertyChanged("SomeIntValue");
            }
        }
    }

    [Display(Name = @"TestString", GroupName = @"TestGroup", Description = @"TestDescription")]
    public string SomeString
    {
        get { return this._someString; }
        set
        {
            if (this._someString != value)
            {
                this._someString = value;
                this.OnPropertyChanged("SomeString");
            }
        }
    }

    [Display(Name = @"Some Subclasses")]
    public IList<IExampleInterface> SubClasses
    {
        get { return this._subClasses; }
        set
        {
            if (!Equals(this._subClasses, value))
            {
                this._subClasses = new ObservableCollection<IExampleInterface>(value);
                this.OnPropertyChanged("SubClasses");
            }
        }
    }

    public IList<IExampleInterface> SubClasses2
    {
        get { return this._subClasses2; }
        set
        {
            if (!Equals(this._subClasses2, value))
            {
                this._subClasses2 = new ObservableCollection<IExampleInterface>(value);
                this.OnPropertyChanged("SubClasses2");
            }
        }
    }

}

最后是 TemplateSelector

And finally the TemplateSelector

  public class TemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        var def = item as PropertyDefinition;
        if (def == null || def.SourceProperty == null)
        {
            return base.SelectTemplate(item, container);
        }

        if (typeof (IEnumerable).IsAssignableFrom(def.SourceProperty.PropertyType) && typeof(string) != def.SourceProperty.PropertyType)
        {
            return this.CollectionsDataTemplate;
        }

        if (typeof (double).IsAssignableFrom(def.SourceProperty.PropertyType))
        {
            return this.FloatNumberTemplate;
        }

        if (typeof (int).IsAssignableFrom(def.SourceProperty.PropertyType))
        {
            return this.IntNumberTemplate;
        }

        return base.SelectTemplate(item, container);
    }

    public DataTemplate CollectionsDataTemplate { get; set; }
    public DataTemplate FloatNumberTemplate { get; set; }
    public DataTemplate IntNumberTemplate { get; set; }
}

这是我所期望的

最佳解决方案是在 TextBlock 中获取详细信息,例如项目 1、项目 2 等.

The optimal solution would be to get detailed Information in the TextBlock, like Item 1, item 2 etc.

谢谢.

//我已经找出了 NullReferenceException 并让 Demo 工作,以便我可以修改文本.但是弹出窗口与默认设置不同.你有修复它的想法吗?

// I've figured out the NullReferenceException and got a Demo to work, so that I can modify the text. But the popup is different to the default. Have you an idea to fix it?

我已经更新了文本和示例.

I've updated the text and the example.

推荐答案

在浪费了几个小时之后,我想出了一个解决方案来实现这一点.

After wasting a few hours now I figured out a solution to realize this.

我已向集合模板添加了自定义行为.加载或更新后,此行为会立即设置 CollectionEditor 的 Header.

I've added a custom behavior to the Collection template. This behavior sets the Header of the CollectionEditor as soon as it's loaded or updated.

下面你可以看到我的修改:

Below you can see my modifications:

模板:

<model:TemplateSelector.CollectionsDataTemplate>
    <DataTemplate>
        <telerik:RadDropDownButton Content="Click to edit the collection">
            <telerik:RadDropDownButton.DropDownContent>
                <telerik:CollectionEditor telerik:AutoBindBehavior.UpdateBindingOnElementLoaded="Source"
                                          ResizeGripperVisibility="Visible">
                    <i:Interaction.Behaviors>
                        <model:CollectionEditorBehavior />
                    </i:Interaction.Behaviors>
                </telerik:CollectionEditor>
            </telerik:RadDropDownButton.DropDownContent>
        </telerik:RadDropDownButton>
    </DataTemplate>
</model:TemplateSelector.CollectionsDataTemplate>

行为:

internal class CollectionEditorBehavior : Behavior<CollectionEditor>
{

    protected override void OnAttached()
    {
        this.AssociatedObject.SourceUpdated += (sender, args) => this.PrepareHeader();
        this.AssociatedObject.DataContextChanged += (sender, args) => this.PrepareHeader();
        this.AssociatedObject.Loaded += (sender, args) => this.PrepareHeader();
    }

    private void PrepareHeader()
    {
        if (this.AssociatedObject == null)
        {
            // Error Case
            return;
        }

        if (this.AssociatedObject.CollectionView == null ||
            this.AssociatedObject.CollectionView.SourceCollection == null)
        {
            // Source not set
            this.AssociatedObject.Header = "Collection";
            return;
        }

        // Get the property from the DataContext to retrieve HeaderInformation
        var propInfo = this.AssociatedObject.DataContext
                           .GetType()
                           .GetProperties()
                           .FirstOrDefault(
                                           propertyInfo =>
                                           Equals(propertyInfo.GetValue(this.AssociatedObject.DataContext),
                                                  this.AssociatedObject.CollectionView.SourceCollection));


        if (propInfo == null)
        {
            // We didn't got the property Information,  using default value
            this.AssociatedObject.Header = "Collection";
            return;
        }

        // Getting the DisplayName Attribute
        var attr = Attribute.GetCustomAttribute(propInfo,
                                                typeof (DisplayNameAttribute)) as DisplayNameAttribute;

        if (attr != null)
        {
            // We have a DisplayName attribute
            this.AssociatedObject.Header = attr.DisplayName;
            return;
        }

        // Alternative: Get the Display Attribute
        var attr2 = Attribute.GetCustomAttribute(propInfo,
                                                 typeof (DisplayAttribute)) as DisplayAttribute;
        if (attr2 != null)
        {
            // We have the Display Attribute
            this.AssociatedObject.Header = attr2.Name;
            return;
        }

        // We have no DisplayAttribute and no DisplayName attribute, set it to the PropertyName
        this.AssociatedObject.Header = propInfo.Name;
    }

}

这篇关于CollectionEditorPicker 的 Telerik RadPropertyGrid 内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆