Winforms PropertyGrid per-GridItem row height - winforms

I'm using the Winforms PropertyGrid; the target of the SelectedObject includes a property of type Image. Everything is fine, except that with all items the same height, the image is too small to see properly. I'd like to have some control over the height of grid items such that the image can be displayed a bit larger. One other detail is that the SelectedObject of one PropertyGrid control may be assigned an object of any of a variety of different classes (which may or may not have image properties), so I'm hoping the height can be driven by data in the instance of the SelectedObject itself, rather than making it a static behavior of the control, although I'd settle for a custom attribute of the image property to make the item height at least class-specific if it can't be instance-specific.
How can I do this? Custom attribute? PropertyGrid event? Something else?

As Simon commented on your question, this is not possible to have a custom height for a GridItem.
You have 2 solutions to be able to show an image with a reasonable size:
You can code your own UITypeEditor. That way, the user would just click the down arrow and see a nicely sized image in the dropdown box.
Sorry for the plug but I think it directly answers your question: only 3rd party PropertyGrids may allow you to get variable size rows in the grid. Smart PropertyGrid.Net is one of them. You set a HeightMultiplier to the row so that it expands on let's say 4 rows. Then you code your own Look class that handles the drawing of the image the way you want in this space.

Related

Switch WPF UI controls dynamically

I need to develop a simple WPF application. In the UI window, There are Labels and Text Blocks towards the left and Buttons towards the right.
Figure 1
Based on a config setting (whether the user is left-handed or right-handed) I need to switch the controls, Buttons towards the left and Labels and Text Blocks towards the right.
Figure 2
Can you please recommend a good way to address this requirement?
Depends what the scope of the app is likely to be.
2 alternatives:
1)
I think it likely as an app grows that there will be more than just buttons.
I would probably build a usercontrol which encapsulates this behaviour for a label and control. The usercontrol uses a static to decide where the textblocks are positioned but would look something like the row edit control in this:
https://gallery.technet.microsoft.com/WPF-Entity-Framework-MVVM-78cdc204
Which is a usercontrol has a contentpresenter in it so you can put any control you like ( such as a button ) "in" it and set a dependency property for the label.
2)
Define 2 contentcontrol templates similar to the one used in this:
https://social.technet.microsoft.com/wiki/contents/articles/28597.aspx
Put them in separate resource dictionaries and give them the same key.
Merge into application.current.resources the appropriate resource dictionary and hence style.
Seeing as this is an app setting, this is presumably a start up thing. People don't just change their "handedness" dynamically. So you could probably use these as staticresource. If they're realistically going to change at run time then I think this would be a bit more involved because you'd need to force re render of a view.
2 Templates are probably the right and stylish solution here as #RajN said.
Also you can define a grid with 2 columns and switch the property 'Grid.Column' of each controls accordingly
Maybe not the best way, but I managed to achieve this using a grid as per your suggestions. Thank you all for your valuable feedback.
I switched the columns and changed the widths accordingly.
if (AppSettings.IsLeft)
{
parentGrid.ColumnDefinitions[0].Width = new GridLength(400, GridUnitType.Pixel);
parentGrid.ColumnDefinitions[1].Width = new GridLength(1, GridUnitType.Star);
Grid.SetColumn(buttonGrid,0);
Grid.SetRow(buttonGrid,0);
Grid.SetColumn(contentGrid,1);
Grid.SetRow(contentGrid,0);
}

WPF Custom Control with Databinding

I'm looking to create a custom control which represents a hand.
This at needs to be bound to a datasource, then if a value/index value is present in the datasource which is representing a particular finger, the finger in question should appear green.
Can anyone point me in the right direction to start of with such control?
Basically I'm creating an app which records which fingers people where their rings and how many.
So graphics on each finger will show Green plus a number showing how many.
Rough Hand Design for User Control
Any help or direction will be mostly appreciative.
I'd recommend a usercontrol rather than custom control for this. As I think that link Clemens posted says, unless you really are going to switch out the template of the control then you don't need to do a custom control - which would be harder than a usercontrol.
This will have at least one dependency property you're going to bind your collection to. Make that an ObservableCollection. You can then pass say 0,1,0,2,0. If people change the rings they wear super dynamically you can set one of the collection to itself to cover change notification to the control.
Inside this I'd put a viewbox with a canvas in it.
Grab an outline of a hand from somewhere. You want to get a geometry out of this so look for a svg preferably.
Maybe https://www.flaticon.com/free-icon/stop-hand-silhouette_57659
Then download and install InkScape.
Use this to trace bitmap if that's all you have then save as > xaml.
Open that file in notepad and you'll see a path with a set of sort of co-ordinates. Grab those. These can be used to define a geometry you use as a resource or directly used as the Data to a path.
I use such a resource for the email "icon" in this:
https://social.technet.microsoft.com/wiki/contents/articles/32610.wpf-layout-lab.aspx
Or you could probably use one of the hand icons from syncfusion's metro studio ( free ) https://www.syncfusion.com/downloads/metrostudio
A Path can be used for your hand.
You then want 5 itemscontrols for your thumbs and fingers.
You could maybe make each of them a usercontrol as well but I'd try 5 controls for a first iteration.
They should template each item they're given into a green rectangle defined in itemtemplate.
Position 5 of them to taste on your hand's digits.
Bind their itemssources by index to your collection and use a converter to return the number of objects specified by that. So if it's 3 then you generate three objects.
That viewbox is there to scale everything. So you can size your control however you like and the rings will stay on the fingers.

Can't set the table width in WPF through

I am making WPF application.I have a data grid and all columns have set their width to "Auto".When i start scrolling through the table some of the columns start expanding.My question is: Can I set the column width to fit the longest data in column at the beginning (without expanding columns when i scroll)?
the column width for wpf expanding when the shown data need more space when it set to Auto then this work will be done automatically.
Well this is due to the virtualization of the DataGrid. Only the items, which are visible are rendered and the controls are reused in case of scrolling (if you are activating it). And so the width will not be correct, since the longest element is not rendered yet. A list control performs very well, although you might bind many items to it.
I think you have 2 options
Turning off the virtualization, which might be a proper solution, if you don't have many items to show. I've to admit, I didn't try it, so no warranty. You can turn it off via <DataGrid VirtualizingStackPanel.IsVirtualizing="False"/>. For more information on the VirtualizationStackPanel pls have a look here.
Another solution may be TextTrimming. TextBlocks can show Ellipses if the text is too long. Therefor you will have to assign a custom datatemplate to the column put the following as content e.g. <TextBlock Text="{Binding}" TextTrimming="WordEllipsis"/>. Please note, that you will also have to provide a customer CellEditingTemplate, if the user shall be able to edit the values. For more information about TextTrimming please have a look here. To get an idea how the whole DataTemplate thing regarding DataGrids will work, you can have a look here.

Silverlight RadGridView change TextBox background

I am facing a small problem using silver light . I have a RadGridView, with four columns. My second columns contains text boxes and the third column contains validation errors. If the third column contains validation errors, i want the second column background to turn red. How can i do this. I have tried binding the text box background column to a string with the desired color but that does not work. Really stuck here. Any help with be much appreciated.
Regards,
Mateen
Assuming your binding is otherwise valid, you cannot change colour by binding to a text string of a colour. The background property is of type Brush.
You need to either bind to a Brush instead, or use a brush/colour converter to return a Brush instead of a Color/string etc.
Try these links for converter examples:
http://forums.silverlight.net/p/20392/70263.aspx
http://forums.silverlight.net/p/20392/70263.aspx
You need a StringToObjectConverter found here. This class has the advantage that it has wider uses that eliminate the need to create a plethora of similar converters.
Further rather than having the bound object have a property called "Background" which tell the UI to "be red". I would be better that the Model had a property called "Status" which is an enum of the possible states the object is in.
Going further and looking at your specific requirement it would be better that your model exposed a boolean IsValid property which a converter could be applied to. See this blog on a generic BoolToValueConverter.

WPF Undo Redo Property System to highlight in red color if value has changed

I have a following requirement for a very complex UI. (Complex here means there are lot of controls in the form [approximately 100]). I am using MVVM (if my problem requires it to slightly go away from MVVM I am ok with it)
My question is for Editable ComboBox and TextBox. But I would say I like to hear a common algorithm which will fit all controls.
Requirement 1 : The user edits the content and goes to next control, the color of the control/text should become red.
Requirement 2 : When the user comes back to the previously edited control and enters the value which was initially present, the color of the control/text should become back to black.
I know the requirement is tough and I have been breaking my head to design a generic algorithm using which I can store the previous value and call a function to change the color of control.
To just give you all an idea, --> I tried storing 2 properties for every TextBox like Default_Text and Text. But since the number of properties are huge, the memory footprint is very huge. Also maintaining so many properties is very tough.
--> I tried adding a Dictionary to every ViewModel to store what values have got changed. But here the problem I faced was giving unique keys to all the controls in my application, which is not very helpful
--> I had even thought and tried about subclassing controls like TextBox, ComboBox and overriding some methods to suit my requirement, but sadly I failed miserabley when I started adding validations and all.
So here I am stuck with designing a generic WPF property system/algorithm to handle all undo redo functionality, changing styles of controls,etc!!!
It will be really great if you experts can guide me in right direction and also help me in developing such an algorithm/system. A sample illustration will be nice though!!!
I found an answer to the above problem. I used attached behavior for this. More details on this link Function call from XAML from StackOverFlow.
When I databind, I store the initial value of the DataBound variable in the Tag property by using Binding=OneWay. Then I have written a attached behaviour for LostFocus event. Whenever the user enters a control and then goes to other control, it fires LostFocus event and calls my attached behaviour. In this, I check whether the value is equal to the value in Tag. If it is same, I display in black else I display in red.
Attached Behaviour rocks in WPF. I can achieve anything from that cleanly without code cluttering!!!!
Another alternative is to use some "dirty" tracking in your models (or viewmodels) and bind to a properties isdirty (and convert it to a color).

Resources