WPF Binding: How to databind to Grid? - wpf

I have created a class Account.
Next, I have created another class ReorderWindowController which has a field/property SelectedAccount of type Account.
Finally, I have written ReorderWindow WPF window xaml file:
<Window ...
<Window.Resources>
<contollers:ReorderWindowController x:Key="WindowController" />
<DataTemplate DataType="{x:Type entities:Account}">
<Grid Width="140" Height="50" Margin="5">
<TextBlock Text="Some awesome text" />
<TextBlock Text="{Binding Name}" />
<TextBlock Text="Even more awesome text" />
</Grid>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid
Name="AccountGrid"
DataContext="{Binding Source={StaticResource ResourceKey=WindowController},
Path=SelectedAccount}">
</Grid>
</Grid>
</Window>
When I run my code, AccountGrid is not showing anything. Why? How do I make object data bind to the Grid and how do I make it use my data template? Thanks.

Instead of a Grid use a ContentPresenter like this:
<Grid>
<ContentPresenter
Name="AccountGrid"
Content="{Binding Source={StaticResource ResourceKey=WindowController}, Path=SelectedAccount}">
</ContentPresenter>
</Grid>

Related

How can I set the binding for a control's property (which is inside DataTemplate and UserControl) to use the ItemSource's given property?

I would like to make a UserControl which have a DataTemplate, and inside that DataTemplate there are controls. I would like to bind to those nested (inside the DataTemplate) controls' properties so I can set them when I reuse this UserControl. The nested controls will use the ItemSource's properties but the property names of the ItemSource's properties could be different.
The UserControl:
<UserControl x:Class="ContextMenu.BaseFilterUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
x:Name="Self">
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="70" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Margin="10"
Text="Owners" />
<Button Grid.Column="1"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="10"
Click="FilteButtonClicked"
Width="40"
Height="40"
x:Name="FilterButton">
<Popup x:Name="FilterBoxPopup"
PlacementTarget="{Binding ElementName=FilterButton}"
Placement="Bottom"
StaysOpen="False">
<Border BorderBrush="Black"
Background="White"
Margin="2">
<ListView ItemsSource="{Binding ElementName=Self, Path=FilterList}"
x:Name="FilterListView"
Height="300"
Width="150">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<!--<CheckBox IsChecked="{Binding IsChecked}" />-->
<!--<TextBlock Text="{Binding Name}" />-->
<!--This is where I don't know how to properly bind eg. the above control, things I tried:-->
<!--<TextBlock Text="{Binding ElementName=FilterListView, Path=FilterElementName}" />-->
<!--<TextBlock Text="{Binding ElementName=Self, Path=DataContext.FilterElementName}" />-->
<!--<TextBlock Text="{Binding ElementName=FilterListView, Path=DataContext.FilterElementName}" />-->
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Border>
</Popup>
</Button>
<TextBlock Grid.Column="3"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="10"
Text="{Binding ElementName=Self, Path=SelectedNames}" />
</Grid>
</UserControl>
This how the UserControl is used, the FilterElementName="Name" is what I would like to set, depending on the list binded with FilterList list:
<local:BaseFilterUserControl FilterList="{Binding Owners}"
FilterElementName="Name"
SelectedNames="{Binding SelectedNames}"/>
In this case the Owners is a simple IReadOnlyList of an Owner class. The Owner class has a string Name property. But I will use this UserControl again with different list eg. where I would like to use the Versions list's Release property (for the TextBlock inside the UserControl):
<local:BaseFilterUserControl FilterList="{Binding Versions}"
FilterElementName="Release"
SelectedNames="{Binding SelectedReleases}"/>
The ListView is properly populated with items, so the FilterList DependencyProperty is working. But the nested controls are only working when I hard code the bindings:
<TextBlock Text="{Binding Name}" />
For this to work you would need to bind the Path-property of your TextBlocks Text-Binding to the FilterElementName property of your UserControl. Unfortunately the Path property of the Binding class is not a DependencyProperty and therefore not bindable.
One way to to achieve your goal would be to use the DisplayMemberPath property of the ListView, which is bindable:
<ListView x:Name="FilterListView"
Width="150"
Height="300"
ItemsSource="{Binding ElementName=Self, Path=FilterList}"
DisplayMemberPath="{Binding ElementName=self, Path=FilterElementName}"/>
If this approach does not work because you need to specify a more complex ItemTemplate, another way would be create a property of type DataTemplate in your UserControl, use that as ItemTemplate in the ListView and specify it from outside like so:
<local:BaseFilterUserControl FilterList="{Binding Versions}"
SelectedNames="{Binding SelectedReleases}">
<local:BaseFilterUserControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Release}" />
</DataTemplate>
</local:BaseFilterUserControl.ItemTemplate>
</local:BaseFilterUserControl>

how to bind .xml file content on a label stored on a url

i have an xml file ,i am trying to bind it to a label but not successfull yet,i used an xmldataprovider to bind it.here is the code for the template i used.,there are several task in my xml file,i am trying to bind the 1st one.
<Window.Resources>
<XmlDataProvider x:Key="TaskList" Source="http://store.tymesheet.com/templates/Graphic-Designer.xml" XPath="tasks"/>
<ControlTemplate x:Key="tasktemplate1">
<Canvas Height="40" Width="850">
<Label Content="{Binding XPath=task[1]}" Height="30" Width="170" Canvas.Top="5" Canvas.Left="150" Background="LightGray">
</Label>
<TextBox Height="30" Width="120" Canvas.Top="5" Canvas.Left="370" Background="AliceBlue"></TextBox>
<Label Canvas.Left="500" Canvas.Top="5">$</Label>
<Button Canvas.Top="8" Height="10" Width="30" Canvas.Left="600" ></Button>
</Canvas>
</ControlTemplate>
</Window.Resources>
and the code for the listbox where the template is used is here
<TabItem>
<Canvas Height="700" Width="850">
<ListBox ItemsSource="{Binding Path=TaskList}" x:Name="listBox" Height="700" Width="850">
<ListBoxItem Template="{StaticResource tasktemplate1}"/>
</ListBox>
</Canvas>
</TabItem>
i am not getting where my binding is going wrong,any help,thnx.
You can't set ItemsSource and manually add ListBoxItem at same time on ListBox. Either specify ItemsSource or add items based on your condition.
In your case if you want to show only first item, remove ItemsSource and set DataContext of ListBoxItem.
<ListBox x:Name="listBox" Height="700" Width="850">
<ListBoxItem DataContext="{Binding Source={StaticResource TaskList}}"
Template="{StaticResource tasktemplate1}"/>
</ListBox>

How to get ContentControl to resolve DataTemplate

Why does this not resolve the datatemplate?
<Window.Resources>
<DataTemplate DataType="system:DateTime" >
<Grid Background="Aqua">
<TextBlock Text="{Binding Day}"></TextBlock>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid>
<ContentControl Content="{x:Static system:DateTime.Now}"/>
</Grid>
Writing a TemplateSelector feels like an overkill.
DataType design suggests the presence of a directive x:Type like that:
<DataTemplate DataType="{x:Type system:DateTime}">
<Grid Background="Aqua">
<TextBlock Text="{Binding Day}" Height="30" Width="100" HorizontalAlignment="Center" />
</Grid>
</DataTemplate>
See the MSDN for more information.

Binding to DataTemplate

I have a button template:
<DataTemplate x:Key="TemplateTest">
<Button Margin="10" BorderThickness="2" Content="{Binding Text}" />
</DataTemplate>
I want to create a textbox and a button whose content is the same as the textbox's text.
<TextBox x:Name="TextBox" Margin="10">TextBox</TextBox>
<ContentControl DataContext="{Binding ElementName=TextBox}"
ContentTemplate="{StaticResource ResourceKey=TemplateTest}" />
But I don't get anything on the button in this way.
#DanPuzey's one still did not work for me in VS2012. Not sure why it did in Kaxaml
This did:
<TextBox x:Name="TextBox"
Margin="10"
Text="Hello World" />
<ContentControl Content="{Binding ElementName=TextBox,
Path=.}"
ContentTemplate="{StaticResource TemplateTest}" />
and
<DataTemplate x:Key="TemplateTest">
<Button Height="100"
Margin="10"
BorderThickness="2"
Content="{Binding Text}" />
</DataTemplate>
This is failing, quite simply, because you aren't setting the content of your content control: setting the DataContext doesn't change anything. Try this:
<ContentControl Content="{Binding ElementName=TextBox}" ContentTemplate="{StaticResource ResourceKey=TemplateTest}" />
The above worked for me in Kaxaml, but if it's not working for you then I'd suggest you try this instead, which explicitly binds to the text of the textbox:
<ContentControl Content="{Binding Text, ElementName=TextBox}" ContentTemplate="{StaticResource ResourceKey=TemplateTest}" />
first you should set the content of your contentControl to be binded to the text
<TextBox x:Name="TextBox" Margin="10">TextBox</TextBox>
<ContentControl Content="{Binding ElementName=TextBox,Path=Text}"
ContentTemplate="{StaticResource ResourceKey=TemplateTest}" />
now you need change the binding of the button:
<DataTemplate x:Key="TemplateTest">
<Button Margin="10" BorderThickness="2" Content="{Binding}" />
</DataTemplate>
I am not sure if {Binding ElementName=TextBox} sets the default Binding.Path.
You might try setting the Path to . : DataContext="{Binding ElementName=TextBox, Path=.}"
Or you can bind directly the Text property of your element:
<TextBox x:Name="TextBox" Margin="10">TextBox</TextBox>
<ContentControl DataContext="{Binding Text, ElementName=TextBox}"
ContentTemplate="{StaticResource ResourceKey=TemplateTest}" />
and
<DataTemplate x:Key="TemplateTest">
<Button Margin="10" BorderThickness="2" Content="{Binding}" />
</DataTemplate>

Caliburn unable to load usercontrol as ActiveView inside Telerik's RadPane

I have recently moved ContentControl on the View(xaml) inside a telerik RadPane like so:
<telerik:RadDocking.DocumentHost>
<telerik:RadSplitContainer Visibility="{Binding UserControlVisible}">
<telerik:RadPaneGroup>
<telerik:RadPane CanUserClose="False" Header="{Binding Operation}">
<ContentControl x:Name="ActiveItem" Margin="10" VerticalAlignment="Top" />
</telerik:RadPane>
</telerik:RadPaneGroup>
</telerik:RadSplitContainer>
</telerik:RadDocking.DocumentHost>
Since, I have done this my UserControls are not injected as the Content inside ContentControl. I have tried to explicitly bind Content Property on ContentControl to ActiveItem but that says, unable to find the associated view.
Any help will be much appreciated.
try to add a datatemplate to the current content:
<DataTemplate>
<ContentControl cal:View.Model="{Binding}" />
</DataTemplate>
Where cal is:
xmlns:cal="http://www.caliburnproject.org"
and bind the active item explicitly.
Now it looks like
<telerik:RadDocking.DocumentHost>
<telerik:RadSplitContainer Visibility="{Binding UserControlVisible}">
<telerik:RadPaneGroup>
<telerik:RadPane CanUserClose="False" Header="{Binding Operation}">
<ContentControl x:Name="ActiveItem" Margin="10" VerticalAlignment="Top" Content="{Binding ActiveItem}">
<ContentControl.ContentTemplate>
<DataTemplate>
<ContentControl cal:View.Model="{Binding}" />
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
</telerik:RadPane>
</telerik:RadPaneGroup>
</telerik:RadSplitContainer>
</telerik:RadDocking.DocumentHost>

Resources