Replacing ItemsControl ContentPresenter entirely with control being rendered - c#

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.

Related

WPF TreeView Selected Item and showing User Controls

I'm getting myself all in a pickle with TreeViews and User Controls; I'm fairly new to WPF so apologies in advance.
Synopsis
I have a collection of VM classes for my TreeView Items.
So the TreeView is bound to a collection of [Parent] VM instances, each of which has a collection of [Child]ren, and each [Child] has other data and other collections (which I won't bore you with).
The TreeView is on the left side of the form, and on the right I have a user control which should only be visible depending on the selected TreeViewItem type.
So, if the selected item of the TreeView is of '[Child]' type then the User Control should be visible.
Problem
I'm struggling with how to detect when an Item in the TreeView is selected so that I can show/hide the User control.
One way I thought of, but do not like, is to bind the 'IsSelected' property of the TreeViewItem to the [Child] VM class, then raise an event up to the main VM,
which would show/hide the UC via DP's. But this requires a whole load of Events etc and to me, just seems, messy.
Summary
For the life of me I cannot work out how to do this, I must be tired or something...or stupid...or both.
All I want to do is select an Item on the TreeView and the appropriate UserControl displays with the relevant data of the TreeViewItem, which I could in Windows Forms very easily, but obviously I'm not thinking about this in a very WPF'ish way at the moment.
Any links to articles etc appreciated.
Big up your chest for any responses.
In your case, i would prefer a DataTemplateSelector. It´s a object which provides a way to select a DataTemplate based on the databound object - here your ViewModel.
Just put a ContentControl in your Window and bind the Content-Property to the SelectedItem-Property of your TreeView. Set the ContentTemplateSelector-Property of the ContentControl to a reference of your own DataTemplate Selector.
The DataTemplateSelector will choose the correct DataTemplate with the defined UserControl by your requirements.
<DataTemplate x:key="VMParent">
<local:ParentUI DataContext="{Binding}" />
</DataTemplate/>
<DataTemplate x:key="VMChild">
<local:ChildUI DataContext="{Binding}" />
</DataTemplate/>
Greetings :)

Multiple pages in a single window C# WPF

Is there a control that allows to choose data, that should be in it? For example: red one - static page, blue is dynamic, below are buttons that allow to switch pages in dynamic part.
I use the dockpanel suite for this:
dockpanel suite
This contol is designed to mimic the vs.net tabs.
Try using a ContentControl databound to a property on your UserControl. Change the property when you want to update the content. Ensure that the property is either and DependencyProperty or that your user control implements INotifyPropertyChanged.
http://msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol.aspx
This is achived by using DataTemplates. You just bind the SelectedItem of the "red" control (e.g. a ListView) to the Content of the "blue" Control (it should be a ContentPresenter).
You add DataTemplates to the Resources accessable by the "blue" control which will then display different content depending on the underlaying class/data.

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.

Prevent resize of content in WPF

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.

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.

Categories