WPF UserControl Binding Problem - wpf

I have the following user control that is embedded within another user control.
<UserControl.Resources>
<DataTemplate x:Key="ContextsTemplate">
<Label Margin="10,0,20,0" Content="{Binding Name}"/>
</DataTemplate>
</UserControl.Resources>
<ItemsControl Name="Contexts"
Background="Transparent"
ItemsSource="{Binding}"
Margin="0,0,0,0"
VerticalAlignment="Center"
AlternationCount="2"
ItemTemplate="{StaticResource ContextsTemplate}">
</ItemsControl>
Here is XAML code for the user control (controlB) above that is embedded in another user control (controlA).
<local:ContextContentsUserControl Height="30" Content="{Binding Contexts}"/>
controlA is displayed on the screen as "(Collection)" but for some reason doesn't show each item in the collections text in the label. Please help.

The problem is here:
Content="{Binding Contexts}"
You meant:
DataContext="{Binding Contexts}"
The reason you got "(Collection)" instead of the content you had defined for controlA is the content you defined in the XAML for ControlA was replaced with your collection. The body of a UserControl's XAML file simply sets its Content property: You replaced it after it was set.

When you declare your ContextContentsUserControl, you are setting its Content property. You need to be setting the DataContext instead:
<local:ContextContentsUserControl Height="30" DataContext="{Binding Contexts}" />

Related

WPF Itemscontrol datatemplate property changing

I'm currently using the following itemscontrol and datatemplate:
<UserControl.Resources>
<DataTemplate x:Key="OrdersTemplate">
<dxlc:LayoutItem Label="CustomerReference" LabelPosition="Top" MaxWidth="300" HorizontalAlignment="Left" Width="300">
<dxe:TextEdit IsEnabled="True" Text="{Binding Path=CustomerReference}" />
</dxlc:LayoutItem>
</DataTemplate>
</UserControl.Resources>
<HeaderedContentControl Header="Steps">
<ItemsControl ItemsSource="{Binding Orders}" ItemTemplate="{StaticResource OrdersTemplate}"/>
</HeaderedContentControl>
The source is just a list with entities.
The problem is that the "CustomerReference" of every object from my source changes when I change it in the textbox. Whats missing here?
Greets
I think in your view model you have added the same object more than once. Instead of creating new object when ever you added to the collection. So when you want to add a object to collection create a new object and add it

WPF Element Binding in a within a Resource control doesnt work

I have some xaml that will just copy text from one text box to another:
<StackPanel Orientation="Horizontal">
<TextBox Width="100" Height="30" Text="{Binding ElementName=src1, Path=Text}" />
<TextBox x:Name="src1" Width="100" Height="30" />
</StackPanel>
Nothing special, works fine. A bit dumb but just an example.
However if I put the StackPanel as a resource in the Window and create dynamically from code, like this:
<Window.Resources>
<StackPanel x:Key="MySP" Orientation="Horizontal">
<TextBox Width="100" Height="30" Text="{Binding ElementName=src, Path=Text}"/>
<TextBox x:Name="src" Width="100" Height="30" />
</StackPanel>
</Window.Resources>
.. then the element binding doesnt work anymore.
Why? and how to make it work? Any ideas gratefully received.
The following Xaml should work just fine
<Window ...>
<Window.Resources>
<StackPanel x:Key="MySP" Orientation="Horizontal">
<TextBox Width="100" Height="30" Text="{Binding ElementName=src, Path=Text}"/>
<TextBox x:Name="src" Width="100" Height="30" />
</StackPanel>
</Window.Resources>
<StaticResource ResourceKey="MySP"/>
</Window>
You could also use it from code
StackPanel mySP = TryFindResource("MySP") as StackPanel;
if (mySP != null)
{
this.Content = mySP;
}
However, what is the reason for you to have a StackPanel in the Windows Resoures?
If you want to be able to reuse it several times you would have to set x:Shared="False" on the Resource but then you'll get an exception saying something like Cannot register duplicate Name 'src' in this scope the second time you add it.
As far as I'm concerned you should not put that in <Window.Resources>. Only styles, static, dynamic resources and such...
http://msdn.microsoft.com/en-us/library/ms750613.aspx
<Window>
<Window.Resources>
</Window.Resources>
<StackPanel x:Key="MySP" Orientation="Horizontal">
<TextBox Width="100" Height="30" Text="{Binding ElementName=src, Path=Text}"/>
<TextBox x:Name="src" Width="100" Height="30" />
</StackPanel>
<Window>
Having a similar issue, trying to get relative binding to my source control - In my case, I'm creating a designer and need the element as a static so styles can use it's dimensions for centering calculations on a canvas.
Taking a line from [WPF Xaml Namescopes],
ResourceDictionary does not use XAML names or namescopes ; it uses keys instead, because it is a dictionary implementation.
So, directly using ElementName in a resource Dictionary simply does not work, because no name will bind without a NameScope. Also attempted reproducing your situation with Style setters, but no luck - one cannot set an object's name via a Style.
Now, the convoluted solution I cam up with is to
Create a DependencyProperty in the code-behind of the class
you're declaring this resource in.
replace ElementName=Root with RelativeSource={RelativeSource
FindAncestor, AncestorType={x:Type namespace:RootClass}} and bind
to said container directly, allowing you to bind to said
DependencyProperty whilst bypassing the names.
If you need bindings to operate between two elements in the same
StaticResource, bind the source to said DependencyProperty as
OneWayToSource or TwoWay, and the destination as OneWay or TwoWay.
1

How to set a data context for listbox item in listbox item template different from the one set as itemsource in listbox

<UserControl.Resources>
<DataTemplate x:Key="LstBoxTemplate">
<TextBlock Text="{Binding Item}" TextWrapping="Wrap" HorizontalAlignment="Left"/>
<Image Grid.Column="2" Margin="0,0,10,0" Visibility="{Binding isVisible,Converter={StaticResource ImageCtlVisibilityConverter}}" Source="/pjct;component/Images/im.png"/>
</DataTemplate>
</UserControl.Resources>
<ListBox x:Name=lstbox ItemsSource="{Binding itemList}" ItemTemplate="{StaticResource LstBoxTemplate}" />
You question needs more detail, and so I may be missing the point...
If your listbox is bound to a collection of custom objects that you control (aka a view model). Then it should be fairly straight forward for you to add a property to the view model that contains the object that you want to bind your listboxitem to...

WPF - Databind to a StackPanel using DataTemplates

I've modified my question since it has changed focus when trying things out.
I narrowed the problem down to the following...
I try to bind the selected Item of a TreeView to a StackPanel (or some other container that can hold User Controls). This container will then display a UserControl, depending on the type of the selected item.
Here is the xaml of the StackPanel (both treeview and stackpanel are in the same window ==> different grid column)
<StackPanel Grid.Column="2" MinWidth="500" DataContext="{Binding ElementName=myTree, Path=SelectedItem, Mode=OneWay}">
<StackPanel.Resources>
<DataTemplate DataType="{x:Type mvTypes:MyTypeA}">
<controls:UserControlA DataContext="{Binding}" />
</DataTemplate>
<DataTemplate DataType="{x:Type mvTypes:MyTypeB}">
<controls:UserControlB DataContext="{Binding}" />
</DataTemplate>
</StackPanel.Resources>
</StackPanel>
When I place a user control directly under the stackpanel (not in the resources), it displays it with the selected object as their datacontext.
Idem if I place a TextBox in it, it will show the correct type of the selected item.
<TextBox Name="textBox1" Text="{Binding}" />
For some reason, placing it within a DataTemplate (even without setting the DataType) results in nothing to display.
Any sugestions. I'm thinking that maybe a StackPanel is not the right control for this, though I can't seem to find other controls that look suitable as containers like this.
Thanks in advance.
Replace the StackPanel in your example with ContentPresenter and instead of DataContext set the Content property. That should work.
Although you have set the Binding on the second custom control, are you setting the DataContext, as the binding is the route to the information and the DataContext is the information it applies this binding information to.
Andrew
You can create a UserControl to display the TreeView and the selection info on the right, all in one. It saves you from creating any custom control. A custom control is basically unnecessary since you do not create anything which didn't exist before.
<UserControl x:Class="NameSpace.SelectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="namespace.Controls"
Height="300" Width="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TreeView Name="customTree">
<!--Items go here-->
</TreeView>
<StackPanel Grid.Column="1" MinWidth="50" DataContext="{Binding ElementName=customTree, Path=SelectedItem, Mode=OneWay}">
<StackPanel.Resources>
<DataTemplate DataType="{x:Type StylingTest:CustomViewModelA}">
<controls:CustomADetailsControl />
</DataTemplate>
<DataTemplate DataType="{x:Type StylingTest:CustomViewModelB}">
<controls:CustomBDetailsControl />
</DataTemplate>
</StackPanel.Resources>
<TextBlock Text="{Binding}"/>
</StackPanel>
</Grid>
</UserControl>
Any other custom behaviour, I'm sure you could create or set in styles/templates here.
Also, you might find one of my other answers useful.
Good luck with wpf, cheers.

How to properly bind a ListBoxItem in WPF?

I have a listbox and I want to iterate over a collection of Bars in my Foo-object.
<ListBox DataContext="{Binding Path=Foo.Bars}" >
<ListBox.Items>
<ListBoxItem>
<ContentControl DataContext="{Binding Path=.}" />
</ListBoxItem>
</ListBox.Items>
</ListBox>
This is the datatemplate I want to use.
<DataTemplate DataType="{x:Type Bar}">
<Label Content="hello stackoverflow" />
</DataTemplate>
If I snoop (--> examine by using the tool Snoop) my application, I notice that the entire collection of Bars is bound to the ContentControl, in stead of just 1.
How can I properly bind so the iteration over the collection goes fine?
You can just set the DataTemplate, and WPF does all the work. Set the ItemsSource to a list of Bar items, and then define a DataTemplate for Bar items.
<ListBox ItemsSource="{Binding Path=Foo.Bars}">
<ListBox.Resources>
<DataTemplate DataType="{x:Type Bar}">
<Label Content="hello stackoverflow" />
</DataTemplate>
</ListBox.Resources>
</ListBox>
You could also set the ItemsTemplate directly by using <ListBox.ItemTemplate> instead of <ListBox.Resources>
See Data Binding Overview at MSDN.
First add your namespace to the Window element (Intellisense) :
xmlns:local="clr-namespace:yourenamespace"
Then the following XAML ( in Window.Resources is a clean way to do it ) :
<Window.Resources>
<ObjectDataProvider x:Key="DataProvider" ObjectType="{x:Type local:Foo}"/>
<DataTemplate x:Key="Template" >
<TextBlock Text="{Binding Bar}"/>
</DataTemplate>
</Window.Resources>
Place the Listbox :
<ListBox DataContext="{Binding Source={StaticResource DataProvider}}" ItemsSource="{Binding Bars}" ItemTemplate="DynamicResource Template" />
But, it depends on your code-behind object, you have to set a constructor to initialise public properties within your object which are ObservableCollection<> preferably (There is some restriction rules with object instance in XAML).

Resources