DateTime Editor in WPF property grid

Grids for WPF Forum

Posted 3 years ago by Bruce Lum
Version: 16.1.0630
Platform: Silverlight Controls
Environment: Windows 7 (64-bit)
Avatar

I'm trying to dynamically add a date property to a WPF property grid at run-time, since it is retrieved from a database. I can get the date property to properly appear via XAML code:

<propgrid:PropertyGrid Name="propertyGrid1"
    Height="217"
    HorizontalAlignment="Left"
    Margin="47,36,0,0"
    VerticalAlignment="Top"
    Width="508" IsSummaryVisible="False">
  <propgrid:PropertyGrid.Items>
    <propgrid:PropertyGridCategoryItem DisplayName="DateTime">
      <propgrid:PropertyGridPropertyItem
          DisplayName="DateTimeEditBox (date only)"
          Description="A DateTimeEditBox used to modify the date of a DateTime.">
        <propgrid:PropertyGridPropertyItem.Value>
          <system:DateTime>10/31/2008 12:00:00</system:DateTime>
        </propgrid:PropertyGridPropertyItem.Value>
        <propgrid:PropertyGridPropertyItem.DefaultValue>
          <system:DateTime>1/1/2008 12:00:00</system:DateTime>
        </propgrid:PropertyGridPropertyItem.DefaultValue>
        <propgrid:PropertyGridPropertyItem.ValueTemplate>
          <DataTemplate>
            <editors:DateTimeEditBox
                Margin="0" BorderThickness="0"
                Value="{Binding Value, RelativeSource={RelativeSource AncestorType={x:Type propgrid:IPropertyDataAccessor}}, Mode=TwoWay}"
                Format="d" />
          </DataTemplate>
        </propgrid:PropertyGridPropertyItem.ValueTemplate>
      </propgrid:PropertyGridPropertyItem>
    </propgrid:PropertyGridCategoryItem>
  </propgrid:PropertyGrid.Items>
</propgrid:PropertyGrid>

However, I have a hard time converting this into equivalent C# code. The following C# code does not work. If I comment out the Value property assignment for the DateTimeEditBox object, only a blank value cell is displayed.

propertyGrid1.IsSummaryVisible = false;
propertyGrid1.Items.Clear();

DateTimeEditBox dateTimeEditor = new DateTimeEditBox();
dateTimeEditor.Margin = new Thickness(0);
dateTimeEditor.BorderThickness = new Thickness(0);
dateTimeEditor.Format = "d";

// This line emits a compile error
dateTimeEditor.Value =
    "{Binding Value, RelativeSource={RelativeSource AncestorType={x:Type propgrid:IPropertyDataAccessor}}, Mode=TwoWay}";   

PropertyGridPropertyItem item = new PropertyGridPropertyItem();
item.DisplayName = "DateTimeEditBox (date only)";
item.Description = "A DateTimeEditBox used to modify the date of a DateTime.";
item.ValueTemplate = new DataTemplate(dateTimeEditor);
item.ValueType = typeof(DateTime);
item.DefaultValue = DateTime.Now;
item.Value = DateTime.Now;
propertyGrid1.Items.Add(item);
 

Any help would be greatly appreciated.

Bruce Lum
Developer
Contact Innovations Inc.

Comments (3)

Posted 3 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Bruce,

It's difficult to create a DataTemplate properly in code.  I'd recommend that you make your DateTimeEditBox-based DataTemplate in your app's Resouces and then use a FindResource() call to get it and assign it to item.ValueTemplate.  That way, you can skip the whole DateTimeEditBox configuration part in C#.

On a side note, the Value line you have there is invalid as VS reports.  You'd need to create a Binding programmatically and then call SetBinding to apply it on the target control.


Actipro Software Support

Posted 3 years ago by Bruce Lum
Avatar

Thanks for your reply.

I wouldn't know how to make a DataTemplate in my application's Resources, let alone make any Resources, because of my lack of knowledge to do so.

However, I found that the following code is working so far, but haven't fully tested it. The code is derived from that of another post.

FrameworkElementFactory factory = new FrameworkElementFactory(typeof(DateTimeEditBox));
factory.SetValue(DateTimeEditBox.MarginProperty, new Thickness(0));
factory.SetValue(DateTimeEditBox.IsReadOnlyProperty, false);
factory.SetValue(DateTimeEditBox.BorderThicknessProperty, new Thickness(0));
factory.SetValue(DateTimeEditBox.FormatProperty, "MMM dd yyyy");

RelativeSource relativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(IPropertyDataAccessor), 1);
factory.SetBinding(DateTimeEditBox.ValueProperty, new Binding("Value") { RelativeSource = relativeSource, Mode = BindingMode.TwoWay });   

PropertyEditor propertyEditor = new PropertyEditor() { PropertyType = typeof(DateTime), ValueTemplate = new DataTemplate() { VisualTree = factory } };
propertyGrid1.PropertyEditors.Add(propertyEditor);

PropertyGridPropertyItem item = new PropertyGridPropertyItem();
item.Tag = 3;
item.DisplayName = "DateTime";
item.Description = "DateTime object";
item.ValueType = typeof(DateTime);
item.DefaultValue = DateTime.Now;
item.Value = DateTime.Now;
propertyGrid1.Items.Add(item);
 

I don't quite fully understand the code that creates the property editor. It does display a Date/Time editor for just the date (in the month day, year format).

Posted 3 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Bruce,

For a DataTemplate, you just copy the DataTemplate you posted in XAML, add an x:Key="SomeKeyValue" attribute to it and put it your Application.Resources.  Then doing a 'this.FindResource("SomeKeyValue") as DataTemplate' call should be able to locate and return it and prevent the whole element factory section of logic you are doing.  There should be a lot of help on the web for putting DataTemplates in Application.Resources and how all that works.

[Modified 3 years ago]


Actipro Software Support

The latest build of this product (v2018.1 build 0675) was released 10 days ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.