Colour picker not displaying for Control property of type 'System.Windows.Media.Color'?

Grids for WPF Forum

Posted 5 years ago by Simon Teague
Version: 14.1.0602
Avatar

Ok, so I'm trying to display the colour picker for a textblock's 'Foreground' property.

As I'm pretty sure this property is of type 'System.Windows.Media.Color', should the colour picker not already be enabled for the textblock's 'Foreground' property?

In terms of my code, things are pretty simple:

XAML:

<TextBlock x:Name="tb" Text="TextBlock"/>

<propgrid:PropertyGrid x:Name="propertyGrid" Width="388" Height="402"/>

Code behind:

var pGrid = FindName("propertyGrid") as PropertyGrid;
var tb = FindName("tb") as TextBlock;

pGrid.SelectedObject = tb;

 

Am I doing something wrong/is this article out-dated? If so, how exactly would I add the colour picker to this property? Or alternatively, can someone please refer me to some sort of docs for actipro; I can't seem to find any at all.

Thanks for any help in advance.

[Modified 5 years ago]

Comments (12)

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

Hi Simon,

The TextBlock.Foreground property is a Brush type, not a Color type.  Our PropertyGrid should be showing a swatch for Brush-based properties and should let you type in a value.  That basic functionality comes out of the box with PropertyGrid.

For a more advanced and much nicer brush selection UI that supports solid and gradient brush selection, you need to also reference our ActiproSoftware.Editors.Wpf.dll assembly and the ActiproSoftware.Editors.Interop.PropertyGrid.Wpf.dll and then configure those editors to get picked up by the PropertyGrid for certain property Types.  There are several ways to do that, all of which are described in our documentation in detail in the "Actipro Editors / Interoperability / PropertyGrid" topic.  After you do that, you'll have very nice UI for selecting brushes.  You can see a demo of the UI in our Sample Browser's "PropertyGrid Integration (Custom)" demo.


Actipro Software Support

Posted 5 years ago by Simon Teague
Avatar

Thanks for linking to that; the colour picker now works correctly for the 'Foreground' property.

 

One final question. So with this extra control, my XAML now looks like:

<propgrid:PropertyGrid x:Name="MyPropertyGrid">
    <propgrid:PropertyGrid.PropertyEditors>
        <propgrideditors:BrushPropertyEditor />
    </propgrid:PropertyGrid.PropertyEditors>
</propgrid:PropertyGrid>

 

The docs mention this briefly, but I'm not sure how to implement it.

How in XAML would I configure a custom control's custom property to load for example a textblock control with 'text' displayed when editing it in the property grid?

[Modified 5 years ago]

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

Hi Simon,

If you want to make a custom property editor for a specific property, take a look at the "Actipro PropertyGrid / User Interface Layer / Propery Editors" topic in the documentation.  That tells you how you can create a PropertyEditor instance and put it in the PropertyEditors collection in your XAML.  You can set the PropertyEditor.ValueTemplate to a custom DataTemplate that contains your TextBlock.  Then you can set other properties like ObjectType, PropertyType, or PropertyName to narrow down which properties it gets applied to.


Actipro Software Support

Posted 5 years ago by Simon Teague
Avatar

Hi, thanks again for the reference in the docs for custom editors.

I've had a look at them, but I'm still a little confused. I want to use an existing custom control rather than creating one myself.

From the docs and what you've said this is what I have:

*For this example I've replaced my custom control with the textbox.

<Window.Resources>
    <DataTemplate x:Key="MyEditor" DataType="myprogram:MainWindow">
        <TextBox Text="test"></TextBox>
    </DataTemplate>

    <propgrid:PropertyEditorsModifier x:Key="{x:Static propgrid:BuiltinEditors.PropertyEditorsModifierKey}">
        <propgrid:PropertyEditorsModifierActionAdd>
            <MyEditor PropertyType="{x:Type TypeX}"/>
        </propgrid:PropertyEditorsModifierActionAdd>
    </propgrid:PropertyEditorsModifier>
</Window.Resources>

Am I going along the right lines? Obviously referring to the datatemplate in this way isn't quite right; I'm just not sure what the correct way is. I'm seeing on other forum posts that people are creating classes that extend propertyeditor; but is this necessary in my case? Do you have any examples?

[Modified 5 years ago]

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

Hi Simon,

We have made a new QuickStart for the upcoming 2014.2 version that shows a very simple example of making a custom property editor for a certain custom data type. 

The main meat of the sample is here and this sort of thing is what you want to do:

<propgrid:PropertyGrid x:Name="propGrid" MinHeight="300" Width="300" SelectedObject="{StaticResource HomeAutomationSettings}">
	<propgrid:PropertyGrid.PropertyEditors>
					
		<!-- Default 'OnOffAuto' type editor -->
		<propgrid:PropertyEditor PropertyType="sample:OnOffAuto">
			<propgrid:PropertyEditor.ValueTemplate>
				<DataTemplate>
					<shared:HorizontalListBox x:Name="listBox" BorderThickness="0" 
						SelectedValue="{Binding Value, RelativeSource={RelativeSource AncestorType={x:Type propgrid:IPropertyDataAccessor}}, Mode=TwoWay, ValidatesOnExceptions=True, ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}">
						<sample:OnOffAuto>Auto</sample:OnOffAuto>
						<sample:OnOffAuto>On</sample:OnOffAuto>
						<sample:OnOffAuto>Off</sample:OnOffAuto>
					</shared:HorizontalListBox>
					<DataTemplate.Triggers>
						<DataTrigger
								Binding="{Binding IsReadOnly, RelativeSource={RelativeSource AncestorType={x:Type propgrid:IPropertyDataAccessor}}}"
								Value="true">
							<Setter TargetName="listBox" Property="IsEnabled" Value="false" />
						</DataTrigger>
						<DataTrigger Binding="{Binding Path=(propgrid:PropertyGrid.IsReadOnly), RelativeSource={RelativeSource Self}}"
								Value="true">
							<Setter TargetName="listBox" Property="IsEnabled" Value="false" />
						</DataTrigger>
					</DataTemplate.Triggers>
				</DataTemplate>
			</propgrid:PropertyEditor.ValueTemplate>
		</propgrid:PropertyEditor>
 
	</propgrid:PropertyGrid.PropertyEditors>
</propgrid:PropertyGrid>

Make sure whatever control is in your custom value template uses a similar Binding to what is above.


Actipro Software Support

Posted 5 years ago by Simon Teague
Avatar

Thanks for that reference again, what I now have I think should work; although currently the property grid doesn't seem to be picking it up.

This is what I put together based on your example:

<propgrid:PropertyGrid x:Name="MyPropertyGrid">
    <propgrid:PropertyGrid.PropertyEditors>
	<propgrid:PropertyEditor PropertyType="{x:Type MyControl}">
	    <propgrid:PropertyEditor.ValueTemplate>
		<DataTemplate>
		    <views:CustomPicker x:Name="CustomPicker" CustomPickerSource="{Binding Path=(DepProperty)}"/>
                    <DataTemplate.Triggers>
		        <DataTrigger Binding="{Binding IsReadOnly, RelativeSource={RelativeSource AncestorType={x:Type propgrid:IPropertyDataAccessor}}}" Value="true">
			    <Setter TargetName="CustomPicker" Property="IsEnabled" Value="false" />
			</DataTrigger>
			<DataTrigger Binding="{Binding Path=(propgrid:PropertyGrid.IsReadOnly), RelativeSource={RelativeSource Self}}" Value="true">
		            <Setter TargetName="CustomPicker" Property="IsEnabled" Value="false" />
			</DataTrigger>
                    </DataTemplate.Triggers>
		</DataTemplate>
	    </propgrid:PropertyEditor.ValueTemplate>
	</propgrid:PropertyEditor>
    </propgrid:PropertyEditor.ValueTemplate>
</propgrid:PropertyEditor>

 Am I doing something obviously wrong here?

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

Hi Simon,

Two things stand out... one is that you are only targeting properties that return a MyControl wth that PropertyEditor.  If your property doesn't return a MyControl then that won't get used.  Second, your Binding on the CustomPickerSource is likely wrong.  You need to use a binding like what we have in our SelectedValue property in our code where it looks for an ancestor IPropertyDataAccessor, etc.


Actipro Software Support

Posted 5 years ago by Simon Teague
Avatar

As for the property this custom property editor is targetting, I'm getting a dropdown for the property I'm intending on targetting - http://i.imgur.com/TpzIDVc.png - it just seems to be empty; so I'm guessing it's an issue within the DataTemplate.

For your second point, I'm binding to a dependency property in code behind that I've used on other parts of XAML in the same file; so I've just changed things a bit to look for that property further up the ancestral tree.

<views:CustomPicker x:Name="CustomPicker" CustomPickerSource="{Binding Path=DepProperty, RelativeSource={RelativeSource TemplatedParent}}"/>

But this is still not working.

I just want to bind the source of the custom picker to a particular dependency property in my code behind which is of a custom data type. Am I approaching this correctly?

[Modified 5 years ago]

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

Hi Simon,

One good way to know if your custom value template is actually getting picked up is to surround your CustomPicker control with something like:

<Border Background="Red" Padding="10">...</Border>

Then look for the red to surround the main editor.

No that Binding won't work.  You need to either use an ElementName sort of binding reference to another controls in your XAML, or a RelativeSource AncestorType to a containing control above your PropertyGrid, and then do the path off one of those.


Actipro Software Support

Posted 5 years ago by Simon Teague
Avatar

Ok, I've now changed the binding use the Window the propertygrid is in as an ancestor:

<views:CustomPicker x:Name="CustomPicker" CustomPickerSource="{Binding Path=DepProperty, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"/>

As well as putting it in the red border you suggested, but it's still not being picked up.

I'm getting no binding errors on the output window, so I'm not sure what exactly isn't working.

[Modified 5 years ago]

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

Hi Simon,

I would think that your target property is not returning a "MyControl"-based object then since it should be getting picked if it is based on what you had typed above.  You could try matching it by PropertyName instead and see if that is working better for you.  If you get stuck, then please make a new simple sample project that shows the issue and email it to our support address.  Reference this thread and rename the .zip file extension so that it doesn't get spam blocked.  Thanks!


Actipro Software Support

Posted 5 years ago by Aled Hughes - Principal Software Engineer, Control Techniques Ltd.
Avatar

Hi,

We've resolved this issue here - it was down to a problem with the property type as you suggested, which meant that the data template wasn't being picked up as expected.

Thanks for your help.

The latest build of this product (v2019.1 build 0683) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.