Prevent resize of content in WPF - c#

I have created a data template for a data class. The width of the grid created by the datatemplate is bound to a property in the data class, ie, the size of the control matters.
I am creating a list of the data class objects, and adding them to an items control in MainWindow.
Update:
I would like to line up the controls from the data list one after another, and not have them resize.
Example:
[---------box1----------][--box2--][------box3-----]
each are the same data template type, and different widths. Perhaps I shouldn't be using itemsControl, but I am unsure of what other control to use to achieve this.
Any help would be much appreciated. I can post XAML

Can you post some XAML.
It can depend on the HorizontalContentAlignment of the ItemsControl or the style of your ItemContainer/ItemPanel.

Related

Replacing ItemsControl ContentPresenter entirely with control being rendered

i'm using an ItemsControl to generate a list of controls based on my model.
When looking at the visual tree, i noticed that each of the rendered control is wrapped in a ContentPresenter. The controls that are added are a 3rd party control and are designed to display a splitter between each control if they are siblings..this allows a user to size each control. For example the following will show a splitter between each of the controls at run time.
<StackPanel>
<3rdPartyControl />
<3rdPartyControl />
<3rdPartyControl />
</StackPanel>
When using an ItemsControl, each of the 3rdPartyControl are wrapped in a ContentPresenter, and thus no splitter is shown. I have tried various ways to try and solve this problem but unable to get this to work unless i write code behind to add each control rather than rely on Xaml.
Does anyone know of a way to replace the contentpresenter completely (in my case with 3rdpartyControl)?
Thanks
In order to replace the ContentPresenter you could derive from ItemsControl and override the GetContainerForItemOverride method to create a specialized container control.
ListBox for example overrides this method to create a ListBoxItem as container for a new item object.
That's true, every element that you add to ItemsControl is wrapped with ContentPresenter, you can find more details about it in the greate series of articles from dr.wpf ItemsControl a-z
One way I would suggest to try is to change ItemsControl to ListBox and make ListBox act like ItemsControl. In this case you can re-style/re-template ListBoxItem and replace ContentPresenter with your control. You would also need to stop selection support. Here is ListBox style that you need to change.

WPF control similar to ObjectListView

I'm writing an application using WPF, and I need to make something that looks like this (see image):
What control should I use for this?
If you don’t need the groupings (the “Hire as chef” and “Seek dinner invitation” headings), then DataGrid should get you close. You can bind its ItemsSource to your collection of items, and define custom columns bound to your items’ properties.
For example, you can use a DataGridTextColumn for “Occupation”, DataGridCheckBoxColumn for “Tells Jokes?”, and DataGridTemplateColumn for more complex properties which require a custom DataTemplate to visualize, such as the main “Person” column or “Cooking skill”.
Edi: It appears that the DataGrid does support grouping as well.
You should go for ListView
http://msdn.microsoft.com/en-us/library/ms754027(v=vs.90).aspx

WPF DataTemplate Show Original Control

In a DataTemplate I want to show the Control which is actually replaced by the DataTemplate. With error validation, this is possible by using <AdornedElementPlaceHolder />. However, this seems not to work in a normal DataTemplate.
I think there would be a simple solution, but just can't find it.
Thanks a lot
This is not possible and here is why. DataTemplate doesn't replace anything. Instead, a control that defines a DataTemplate contains the content provided by it. If it was possible then there would be an infinite loop (control -> data template -> control -> data template -> ...).
I suggest you read the following article to fully understand data templates: http://msdn.microsoft.com/en-us/library/ms742521.aspx
A DataTemplate in some sense "replaces" a data object and not a UI object - in other words, not a Control. If you are trying to work with properties of the Control (usually either a ContentControl or ItemsControl) that is using the template, try a RelativeSource Binding where the AncestorType is the type of the Control.

Instantiate ItemsPanelTemplate

I'm trying to create a ItemsControl that has a separator between items, for example a control to create a navigation bread crumb. I want the control to be completely generic.
My original method was to create extend ItemsControl, add a SeparatorTemplate property, and then have the class add separators to the ItemsHost of the ItemsControl. The problem with this approach is that if you add extra items to the container panel, the ItemGenerator gets confused and the items are out of order and don't get removed correctly.
So my second plan was to create a completely new control that would emulate an ItemsControl, but the problem I'm running into is that I can't find a way to instantiate an ItemsPanelTemplate. I would like to provide an ItemsPanel property just like ItemsControl, but I can't then create a panel from that template.
Can anyone think of a way to either instantiate an ItemsPanelTemplate or way to add controls to an ItemsControl's panel without breaking the ItemGenerator?
Well I haven't tried it myself but I would have thought you would override the GetContainerForItemOverride to acheive this.
You could create a new BreadCrumbItem control which is a templated ContentControl that has in its default template the typical ContentPresenter and whatever you want to use by default as separator all in a Grid or StackPanel.
The GetContainerForItemOverride generates a new instance of this BreadCrumbItem sets its ContentTemplate to the ItemTemplate property from your ItemsControl derivative (the BreadCrumb control?).
Your BreadCrumb control would also expose BreadCrumbItemStyle property that you assign to the BreadCrumbItem you create during GetContainerForItemOverride.
For completeness you may need to also implement the other *Container*Override methods in your BreadCrumb control.

How do I add additional data to a DataGridRowGroupHeader?

I have a DataGrid that is showing some data via a PagedCollectionView with one group definition. I have created a Style for the corresponding DataGridRowGroupHeader under which I have added a ControlTemplate containing an additional TextBlock and a spacing Rectangle. I would like to bind the widths of these controls to the widths of particular columns, but I am struggling to get this working. I would also like to bind the Text property of the TextBlock to a value.
I tried binding the widths via the Width property of a Rectangle in resources but this didn't work (possibly because the Rectangle was never drawn and therefore didn't calculate it's layout).
However, I believe both sets of bindings can be performed with some use of one or more ValueConverter implementations, but I was wondering if there was a better way. Can any of this be achieved through the definition of a ControlTemplate?
After some trial and error I was able to customize my row group headers. The key to unlocking the solution involved both the RowGroupHeaderStyles property and the LoadingRowGroup event on the DataGrid.
By defining one or more styles for the groups, I was able to customize the control template to include additional named elements. I then used the event to gain access to those elements and either set or bind the relevant values to show the information I required. The only stumbling I had related to binding the size of controls, which I eventually worked around by saving a reference to each row and setting those sizes when it was necessary to refresh them rather than relying on bindings. This may be specific to my project so your mileage may vary.
Update
JDM asked how you get the controls to perform binding etc. in the LoadingRowGroup event handler. You can get the row header from the DataGridRowGroupHeaderEventArgs.RowGroupHeader property of the event arguments and then use the VisualTreeHelper to get the child controls of the header. Once you have the controls, you can bind to them in code as you would any other control.

Categories