Dynamicly putting Object to many visual parents in WPF - wpf

I want to create my own usercontrol which will take some FrameworkElement as parameter (as Content) and then it will didplay it on few copies (how much? it depends) Anyway copies has to be binded to their VM. Single copy will be probably a StackPanel with few binded buttons and TextBoxes. So it will look like this:
<MyControl> <Panel with stuff in it/> </MyControl>
Now in my control I hot ItemsControl and I am dynamicly putting there items. But one content (stack panel for example) can only has one parent so it doesn't work. How can I achive this? I heard that DataTemplates can help me but I don't know how. Also I wander if I can't do something like this:
<MyControl> <ViewModel of Panel with stuff/> </MyControl>

You need to take a DataTemplate property that contains the FrameworkElement(s), then create ContentPresenters in the control, with their Content set to the piece of ViewModel and their ContentTemplate set to your DataTemplate property.

Related

Issue : ListBox hides all the stack panel and text boxes with in them, Wpf

I want to bind my textboxes in wpf xaml. That is doing perfectly but when i get textbox with his x:Name="myTextbox" in codebehind. He says
"The name 'myTextbox' does not exist in the current context"
Using WPF, you cannot access items by name if there are inside a DataTemplate, like in your case, probably. However is not a good practice to modify the template using code behind. If you want to use correctly WPF, take a look at MVVM pattern.
In your case, the ListBox should be bound to an ObservableCollection and inside the template you can bind your textbox or whatever you have to the Item object.
Don't access the textbox like this : x:Name="myTextbox"
Instead access it like myTextbox.Text = "Hello World";.

XAML property path for templates

I have the following hierarchy in my XAML:
Grid
Ruler
Ruler
ScrollViewer
ItemsControl
ItemsControl.ItemsPanel
ItemsPanelTemplate
DrawingCanvas
Here Ruler and DrawingCanvas are my UserControls. DrawingCanvas exposes a property named MousePosition that I want both Rulers to bind to. After reading about PropertyPath Syntax, I tried the following:
Chip="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Mode=OneWay, Path=Children[2].(ScrollViewer.Content).(ItemsControl.ItemsPanel).(local:DesignerCanvas.MousePosition).X}"
but this doesn't seem to work. What am I doing wrong?
Generally in these circumstances you would simply name the element you wish to bind to. It is much less brittle than finding your way through the tree:
Chip="{Binding MousePosition.X, ElementName=myCanvas}"
However, because your canvas is part of the ItemsControl template, the ElementName will not be visible to elements outside the ItemsControl.
In order to bind the two together, you need some intermediate property that both can see. One way would be to declare a DependencyProperty in your code-behind for the view. Both your Canvas and Rulers could then bind to that property using ElementName on the view root.
Another alternative is to hijack the Tag property that every element has, so in your case you could use ItemsControl.Tag as the intermediary:
Chip="{Binding Tag.X, ElementName=myItemsControl}"
<DrawingCanvas MousePosition={Binding Tag,
ElementName=myItemsControl,
mode=OneWayToSource} />
You are selecting element 3 in the Children collection which will map to the fourth element inside of the Grid. You are looking for Children[2].

Grid with content from Binding

I have a library that generates a Grid based on input parameters. The Grid may contain different controls based on the input. I want to create a ListBox where each list item will get its own generated Grid. Is this doable? I couldnt find any Panel-derived (Gird, StackPanel etc) that expose the Content property like Button for example.
How are you passing the data to build the Grid?
I'll assume you have a control that receives the data via a Dependency Property. I.e. you have something like MyControl.MyData property, where MyData is a Dependency Property. In that case, try using a DataTemplate.
Make an ObservableCollection where each item is the data you need to pass in order to build the grid.
On the instance of the ListBox, define ItemTemplate to use a DataTemplate consisting of your control.
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<myAssembly:MyControl MyData="{Binding }"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
#XAMeLi is almost right on the money with his answer - what would be better is a DataTemplateSelector, that way each data item can have a different template (or generated grid). In your class that extends DataTemplateSelector you can easily generate or load the appropriate grid layout as either a separate control or as a dynamic DataTemplate.
Check this article for a good example: WPF Tutorial - How To Use A DataTemplateSelector

WPF "Insert" control per binding

I have a UserControl without Content, because the control which should be shown inside of the UserControl is created at runtime. I would like to solve this like follows, but don't know how to implement it:
Create a Control-variable in the ViewModel
Set it at runtime when the content is created
Bind a content property (inside the UserControl) to that variable
The problem is, that I don't know how to bind to the control-variable.
Why just not to use ContentControl instead of UserControl and provide Content in runtime by introducing a DataTemplateSelector which able to provide right DataTemplate in runtime?
You can encapsulate your Content-area controls in DataTemplates and select appropriate one in runtime.

WPF: Binding items added to UserControl's exposed children

I have a user control that allows items to be added to it by exposing a Grid's Children property. Any control I add shows up fine but when I try to bind a property on the added item to a control in the main window nothing happens (example):
<TextBox Name="txtTest" Text="Success!" />
<mycontrols:CustomUserControl.ExposedGridChildren>
<TextBox Text="{Binding ElementName=txtTest, Path=Text, FallbackValue=fail}"/>
</mycontrols:CustomUserControl.ExposedGridChildren>
This example always results in the TextBox's text showing "fail". Here is how I'm exposing the children in the user control:
public UIElementCollection ExposedGridChildren
{
get { return grdContainer.Children; }
}
Any thoughts? Is it a scope issue? I know I can't name the elements I add to the children because of scope errors. Thanks, Brian.
This might answer your question:
How do you bind a grid's children to a list?
Or as Dr. WPF puts it: (http://drwpf.com/blog/2007/10/15/itemscontrol-a-is-for-abundance/)
Is a Panel an ItemsControl?
No. The logical children of a panel
are UIElements, whereas the logical
children of an ItemsControl (its
Items) can be any CLR objects.
Sidebar: So what is a panel? The main
role of a panel is to provide layout
support for its children. Although a
panel does maintain a collection of
child elements, it is not technically
a WPF “control”… That is, it does not
derive from the Control base class and
it does not support the WPF notion of
templating. Instead, it is a single
element with a single purpose… namely,
to size and position (a.k.a., measure
and arrange) its children.
I was apparently going about this thing all wrong. What I needed to do was create a look-less control and template it to have one (or more) contentpresenter(s).

Resources