How to get control parent DataContext for element to element databinding? - silverlight-4.0

Suppose I have a user control which datacontext is bound to a VM. This VM has a property for a list MyList.
Inside this user control I have a ComboBox, I want to set following kind of xaml
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel HorizontalAlignment="Stretch">
<sdk:DataGrid ItemsSource="{Binding YourList}" IsReadOnly="True" AutoGenerateColumns="False" >
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Header="Name" Binding="{Binding Name}" />
<!-- ...... -->
<sdk:DataGridTemplateColumn Header="User" >
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding ElementName=LayoutRoot, Path=DataContext.MyList}" DisplayMemberPath="Value" SelectedValuePath="Key" SelectedValue="{Binding UserID}" ></ComboBox>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</StackPanel>
</Grid>
but it is not working.
How to resolve this problem?

This worked form me. This was the ItemSource for a ComboBox that was within a DataGrid:
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=sdk:DataGrid},
Path=DataContext.Teams}">

Are you trying to get to the main VM from within the UserControl? take a look at this solution. http://weblogs.asp.net/dwahlin/archive/2009/08/20/creating-a-silverlight-datacontext-proxy-to-simplify-data-binding-in-nested-controls.aspx

Related

How to find LongListMuliselector inside another ListBox

I need to find the LongListMultiSelector inside ListBox .
<ListBox x:Name="ListBoxName" Width="400">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Bewise:ExpanderControl x:Name="bewiseControl" HeaderText="{Binding Title, Mode=OneWay}" Width="400" >
<Bewise:ExpanderControl.ContentArea>
<toolkit:LongListMultiSelector ItemsSource="{Binding LstProdcuts}" x:Name="LongList">
<toolkit:LongListMultiSelector.ItemTemplate >
<DataTemplate>
<StackPanel >
<TextBlock Text="{Binding Title}" />
</StackPanel>
</DataTemplate>
</toolkit:LongListMultiSelector.ItemTemplate>
</toolkit:LongListMultiSelector>
</Bewise:ExpanderControl.ContentArea>
</Bewise:ExpanderControl>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
i need to access LongList inside ListBoxName.I needed this LongList to get the selected item and itemSource or to add item to the selecteditem of the list
You could use the VisualTreeHelper class in order to access elements within.
Example!

How to add Command to ListBox.ItemTemplate

I have a WPF application using MVVM.
This code is from my ResourceDictionary.xaml
<DataTemplate x:Key="LogListTemplate">
<ListBox ItemsSource="{Binding LogList, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource HorizontalListBoxItem}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Style="{StaticResource ErrorBorders}">
<StackPanel ToolTip="{Binding Details}" Width="250">
<TextBlock Text="{Binding Title}" />
<TextBlock Text="{Binding Details}" TextWrapping="Wrap" />
<Button Command="{Binding AddToTempDtdFileCommand}" CommandParameter="{Binding Details}" Content="Ignore" />
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
When I click on Button, the command does not execute. Testing confirms this is because my Button lives within a ListBox.
My problem is I can't move my button out of the ListBox for 2 reasons.
1. Asthetics/UI (the button has belong with the information)
2. Binding to the LogList is done from within the ListBox.ItemTemplate
Does any one have any suggestions?
If the command is defined in the ViewModel you can reach it by using RelativeSource. RelativeSource can find an ancestor (which is your View) so you can use its DataContext (your ViewModel).
<Button Command="{Binding DataContext.AddToTempDtdFileCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type YourViewClass}}}" CommandParameter="{Binding Details}" Content="Ignore" />

Bind ListBox in DataTemplate to parent control DataMemberBinding - Silverlight XAML

Just wondering if it's possible to bind the listbox in the XAML below to the GridViewDataColumn in a relative manner - I can do it explicitly but I want to add the Columns dynamically and would like to set up some logic in the the Column's Converter.
<navigation:Page.Resources>
<converters:DebugConverter x:Key="DebugConverter"/>
<converters:DebugInnerConverter x:Key="DebugInnerConverter"/>
<DataTemplate x:Key="ChemistryResultsTemplate">
<ListBox><!-- Bind this to parent GridViewDataColumn data -->
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ProfileResult}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</navigation:Page.Resources>
<Grid x:Name="LayoutRoot">
<telerik:RadGridView x:Name="LabReportGrid" AutoGenerateColumns="True">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding="{Binding ChemistryResults, Converter={StaticResource DebugConverter}}"
CellTemplate="{StaticResource ChemistryResultsTemplate}"
x:Name="Testing">
</telerik:GridViewDataColumn>
</telerik:RadGridView.Columns>
</telerik:RadGridView>
</Grid>

Using different databinding sources within ListBox and ContextMenus

Here is the XAML:
<ListBox ItemsSource="{Binding Documents}" BorderBrush="{x:Null}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Title}" FontSize="12" FontWeight="Bold" />
<TextBlock Text="{Binding ID}" FontSize="10" FontStyle="Italic" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ContextMenu>
<ContextMenu ItemsSource="{Binding CategoryList}">
<ContextMenu.ItemTemplate>
<DataTemplate>
<MenuItem Command="{Binding AddDocumentToCategoryContextMenuCommand}" Header="{Binding Category.Name}" />
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
Ok so the ListBox's ItemSource is bound to the Documents collection in the VM and properly renders the Titles and IDs
The Context Menu's ItemSource is bound to the CategoryList collection in the VM and properly renders the list of categories.
The problem I have is with the Command Binding:
Command="{Binding AddDocumentToCategoryContextMenuCommand}"
Since the ItemSource for the ContextMenu is already set, it tries to get the AddDocumentToCategoryContextMenuCommand from CategoryList. Obviously the command is not there, it is a member of the VM.
I do not want any references to the VMs or Models in the XAML. Everything is constructed using Unity and VM-View is associated in App.xaml:
<Application.Resources>
<DataTemplate DataType="{x:Type vms:FeedViewModel}">
<views:FeedView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vms:DocumentsViewModel}">
<views:DocumentsView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vms:ManagementViewModel}">
<views:ManagementView/>
</DataTemplate>
<DataTemplate DataType="{x:Type dev:DevelopmentViewModel}">
<dev:DevelopmentView />
</DataTemplate>
</Application.Resources>
How can I databind to a member of the VM from within the ContextItem.
Thanks.
UPDATED edit #1 starts Here
Here is the updated xaml (but still not working but some insight gained):
<ListBox ItemsSource="{Binding Documents}" x:Name="Results" BorderBrush="{x:Null}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Title}" FontSize="12" FontWeight="Bold" />
<TextBlock Text="{Binding ID}" FontSize="10" FontStyle="Italic" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ContextMenu>
<ContextMenu ItemsSource="{Binding CategoryList}">
<ContextMenu.ItemTemplate>
<DataTemplate>
<MenuItem Command="{Binding ElementName=Results, Path=DataContext.AddDocumentToCategoryContextMenuCommand}" Header="{Binding Category.Name}" />
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
I have this example working for a simple example that does not use a ContextMenu. It appears that the ContextMenu (even though attached to the ListBox) is not part of the user control visual tree. The binding always comes back null / not found. I think the ContextMenu, because it is a floating "window" is constructed in its own tree and therefore cannot find the ListBox call "Results" in order to access the ListBox's DataContext.
Any thoughts on this? Any recommendations on how deal with?
Edit #2 Starts Here
In case you are are wondering, figured out the answer to the binding question:
This binding works:
Command="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.DataContext.AddDocumentToCategoryContextMenuCommand}
Hope this helps others with the same question.
One last update for completeness.
In order for the command to know which context menu item was clicked on, I had to change the xaml slightly (silly oversight):
<ListBox.ContextMenu>
<ContextMenu x:Name="Context" ItemsSource="{Binding CategoryList}">
<ContextMenu.ItemTemplate>
<DataTemplate>
<MenuItem Command="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.DataContext.AddDocumentToCategoryContextMenuCommand}"
CommandParameter="{Binding Category.ID}"
Header="{Binding Category.Name}" />
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</ListBox.ContextMenu>
Again, hope this helps others.
Use the ElementName property of the binding to specify that. You'd end up with something like this:
Command="{Binding ElementName=ViewModelObject
Path=AddDocumentToCategoryContextMenuCommand}"

how to (define and call events for a child datagrid) within the data grid

i need to define events for the datagrid with in another datagrid(master child grid)
now i need to define events for child grid and call those events when i click the child data grid
i have define events for child data grid in xaml page. but these events or not getting fired. how should i go ahead ?
RowDetailsVisibilityChanged="dgrdRowDetail_RowDetailsVisibilityChanged"
is my Xaml code
<sdk:DataGrid MinHeight="100" x:Name="dgCounty" AutoGenerateColumns="False" VerticalAlignment="Top" Grid.Row="1" IsReadOnly="True" Margin="5,5,5,0" RowDetailsVisibilityChanged="dgCounty_RowDetailsVisibilityChanged" SelectionMode="Extended" RowDetailsVisibilityMode="VisibleWhenSelected">
<sdk:DataGrid.Columns>
<sdk:DataGridTemplateColumn>
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button x:Name="myButton" Width="24" Height="24" Click="Details_Click">
<Image x:Name="img" Source="Images/detail.JPG" Stretch="None"/>
</Button>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
<sdk:DataGridTemplateColumn Header="ID">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate >
<sdk:Label Content="{Binding EmployeeID}" />
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
<sdk:DataGridTemplateColumn Header="Name">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate >
<sdk:Label Content="{Binding EmployeeFName}" />
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
<sdk:DataGridTemplateColumn Header="MailID">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate >
<sdk:Label Content="{Binding EmployeeMailID}" />
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
</sdk:DataGrid.Columns>
<sdk:DataGrid.RowDetailsTemplate>
<DataTemplate>
<sdk:DataGrid x:Name="dgrdRowDetail" Width="400" HeadersVisibility ="None" AutoGenerateColumns="False" HorizontalAlignment="Center" IsReadOnly="True" RowDetailsVisibilityChanged="dgrdRowDetail_RowDetailsVisibilityChanged" SelectionMode="Extended" RowDetailsVisibilityMode="VisibleWhenSelected">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Binding="{Binding CompanyName}"/>
<sdk:DataGridTextColumn Binding="{Binding CompanyID}"/>
<sdk:DataGridTemplateColumn Header="Score">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate >
<StackPanel Loaded ="StackPanel_Loaded" Orientation="Horizontal" Background="Transparent">
<TextBlock Text="{Binding Score}" TextWrapping="NoWrap" HorizontalAlignment="Center" Foreground="Blue"></TextBlock>
<Image x:Name="imgScore" Source ="{Binding Score}" Width="20" Height="20" Stretch ="Fill"/>
</StackPanel>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</DataTemplate>
</sdk:DataGrid.RowDetailsTemplate>
</sdk:DataGrid>
private void dgrdRowDetail_RowDetailsVisibilityChanged(object sender, DataGridRowDetailsEventArgs e)
{
}
does any one knows how to define and call the events of child datagrid. any help would be great looking frwd for an solution.
thanks in advance
prince
Soution:
define globally
DataGrid dgrdRowDetail;
in event parent event we can fine the child data grid and then define the event for the child data grid to.
private void dgCounty_RowDetailsVisibilityChanged(object sender, DataGridRowDetailsEventArgs e)
{
dgrdRowDetail = (DataGrid)e.DetailsElement.FindName("dgrdRowDetail");
dgrdRowDetail.RowDetailsVisibilityChanged+=new EventHandler<DataGridRowDetailsEventArgs>(dgrdRowDetail_RowDetailsVisibilityChanged);
}
once you get your dgrdRowDetail which is the child control then yoy can perform all the actions against it like binding,events all those stuff.