How Datacontext is specified can not understand - wpf

Here in mMaterialCentreGroupListView.xaml file, this line is written for MaterialCentreGroupView . But I can not see any data context for accessing viewmodel's property. It is working good. Below is code.
<vw:MaterialCentreGroupView
Style="{StaticResource DetailedViewStyle}"
DataContext="{Binding SelectedMaterialCentreGroup}"/>
the view
<UserControl x:Class="MyBooks.View.MaterialCentreGroupView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
MinWidth="290" MaxWidth="290" Padding="20"
Background="#eee">
<UserControl.Resources>
<ResourceDictionary Source="ViewResources.xaml" />
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label
Grid.Row="0" Grid.Column="0"
Content="{Resx ResxName=MyBooks.Properties.Strings, Key=AccountCategoryListView_Name_Label}"
HorizontalAlignment="Right"/>
<TextBox
x:Name="CategoryName"
MaxLength="50"
Style="{StaticResource FormControlStyle}"
Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2"
Text="{Binding Path=Name, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"/>
Please explain to me what happen and how binding is occur?

I would assume the DataContext is either set in the code-behind (file named the same as the .xaml file but with .cs extension). Look for code like DataContext = new SomeViewModel();
Or, if this UserControl is being used within another control, the DataContext could be either explicitly set on it or, if not, it would be inherited from its parent (which may or may not be inherited from its parent, and so on, if not set explicitly in either the XAML or code-behind).

look 'Resx' binding
<Label
Grid.Row="0" Grid.Column="0"
Content="{Resx ResxName=MyBooks.Properties.Strings, Key=AccountCategoryListView_Name_Label}"
HorizontalAlignment="Right"/>
more information about resx binding and usage ,refer the below link
Resx binding and usage

Related

TreeViewItem Tooltip Binding Not Working

I have a treeview. It's bound to an ObservableCollection called Nodes. The bound data on the tool tips is not showing:
<controls:TreeViewEx BorderThickness="0"
ItemsSource="{Binding Nodes}"
SelectedItemEx="{Binding SelectedTreeNode, Mode=TwoWay}">
<controls:TreeViewEx.ToolTip>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Row="0"
Grid.Column="0"
Source="/FMG.UI.WPF;component/Media/Images/job_128.png"
Height="16"
Width="16"/>
<TextBox Grid.Row="0"
Grid.Column="1"
Text="Job: "
FontWeight="Bold"/>
<TextBox Grid.Row="0"
Grid.Column="2"
Text="{Binding ToolTipHeader}"/>
<Border Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="3"
Height="2"
BorderBrush="Gray"/>
<TextBox Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="3"
Text="{Binding ToolTipDetails}"/>
</Grid>
</controls:TreeViewEx.ToolTip>
</controls:TreeViewEx>
The tooltip pops up, but the ToolTipHeader and and ToolTipDetails are blank. The Output window says it can't find them on the view model. How do I make the binding look on the Node, not the view model?
You probably want to move the code; use the TreeView.ItemContainerStyle and add a Setter for the ToolTip, this will set a node-level tool-tip.
e.g.
<controls:TreeViewEx.ItemContainerStyle>
<Style TargetType="controls:TreeViewItemEx"> <!-- Guessing at item type name here -->
<Setter Property="Tooltip">
<Setter.Value>
<!-- Move your tooltip here -->
</Setter.Value>
</Setter>
</Style>
</controls:TreeViewEx.ItemContainerStyle>
Of course the DataContext for all the bindings in the tooltip will be the current item, if you want the context of the tree-view specify a RelativeSource that finds it (also prepend "DataContext" on the Path, otherwise you bind to properties directly on the tree-view).

Nested data template

I need to reuse an existing data template, defined as a reource, in a data template defined in a control
...this is my customer data template as a resource so it can be a reusable object
Customer DataTemplate:
<ResourceDictionary ... >
<DataTemplate DataType="{x:Type Model:Customer}">
<StackPanel Orientation="Vertical" Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="140" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<TextBox Text="{Binding CustomerName}"
Grid.Column="0" Grid.Row="0" />
</StackPanel>
</DataTemplate>
</ResourceDictionary>
now I need to reuse the Customer data template defined above in a user control data template
<UserControl x:Class="MyCustomerControl"
<UserControl.Resources >
<DataTemplate DataType="{x:Type frnri:CustomerViewModel}">
question: How can I reuse customer data template here?
</DataTemplate>
</UserControl.Resources>
</UserControl>
Is possibile this scenario WITHOUT defined the customer data template inline in the MyCustomerControl?
Place your datatemplate in App.xaml, then it will be available throughout your program.
Declare the resource as follows
<Application.Resources>
<DataTemplate DataType="{x:Type Model:Customer}" x:Key="customerTemplate">
<StackPanel Orientation="Vertical" Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="140" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<TextBox Text="{Binding CustomerName}"
Grid.Column="0" Grid.Row="0" />
</StackPanel>
</DataTemplate>
</Application.Resources>
Then you can reference it in your UserControl like
<ListBox ItemTemplate="{StaticResource customerTemplate}" />
The same will work for the ResouceDictionary

WPF - Bind to selecteditem of listbox between user controls

I have two usercontrols, the first with a listbox that is bound to a list of Customers that displays some simple details for each customer.
The second user control I would like to be a more detailed view of whichever customer is selected in the listbox of the first usercontrol.
Is it possible to set up a binding in the second control to bind to the selected item in the first user control?
My List box:
<ListBox Name="lstCustomer" ItemsSource="{Binding Customers}" >
<ListBox.Resources>
<DataTemplate DataType="{x:Type MyApplication:Customers}">
<Label Grid.Row="0" Content="{Binding Customer.name}" FontSize="14" FontWeight="Bold" Padding="5" />
<Label Grid.Row="1" Grid.Column="0" Content="{Binding Customer.telephone}" Padding="10,5" />
</Grid>
</Grid>
</DataTemplate>
</ListBox.Resources>
</ListBox>
Detailed view Usercontrol (So Far)
<Grid x:Name="containingGrid" DataContext="{Binding ElementName=lstCustomers, Path=SelectedItem}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Customer.name}" FontSize="23"/>
</Grid>
Thanks
Greg
I would suggest to have a property in your ViewModel of Customer object say SelectedCustomer and bind it to the SelectedItem of your listbox like this -
<ListBox Name="lstCustomer" ItemsSource="{Binding Customers}"
SelectedItem = "{Binding SelectedCustomer}" >
. . . . .
</ListBox>
Since you mentioned that both user controls are in same view, so i am assuming that they share a same ViewModel. In that case you can simply set the data context this way -
<Grid x:Name="containingGrid" DataContext="{Binding SelectedCustomer}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" FontSize="23"/>
</Grid>
Yes, you can - if you give the listbox a name of CustomerList then you can bind to its SelectedItem property using a binding like "{Binding ElementName=CustomerList, Path=SelectedItem}".

WPF (VS2010/.NET4.0) Create a re-usable form layout

In a nutshell what Im trying to achieve is to have a re-usable DLL which will potentially have a wizard like form. I could then simply set the content. Ive spent quite a bit of time searching but Im still not sure whats the best way to go. Ive had a look at this article as well.
Ive got the following structure in the XAML code:
<Grid x:Name="MainGrid">
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="30"/>
<RowDefinition Height="20"/>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
<RowDefinition Height="30"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" Content="{Binding ScreenTitleText}" />
<Label x:Name="ContentTitle" Grid.Row="3" Grid.Column="2" Grid.ColumnSpan="2" Content="{Binding ContentTitleText}" />
<Button x:Name="BackButton" Grid.Row="5" Grid.Column="1" Content="Back" />
<Button x:Name="NextButton" Grid.Row="5" Grid.Column="3" Content="Next" />
<ScrollViewer Grid.Row="4" Grid.Column="2" Content="{Binding InnerContent}" x:Name="InnerControl"/>
</Grid>
Id like to know how to make it so that I could set the content on row=4 and column=2 to say for example a set of radio buttons.
How to have this code in a DLL so that I could re-use it.
Thanks!
Create this as a WPF User Control in a Class Library or a WPF User Control Library. Then, put ContentControls where you want the dynamic stuff to go. You can expose DataTemplate properties for each of those ContentControls. The ContentControls can bind their Template to a DataTemplate and you should be good to go.

WPF: Is VerticalAlignment inherited by nested containers?

I'd like to have the nested containers inherit that property, but when I set it in the outermost one I'm not sure if it's working. It either is working but I'm not getting the results I want, or maybe I'd have to set up a property somewhere for it to carry.
Assuming that a) it is possible to do it and b) I'd have to change a property somewhere, would that have any side effects I should be aware of?
EDIT
Ok, here's an example:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test" Width="300" Height="100">
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0">Text</Label>
<TextBox Grid.Row="0" Grid.Column="1">I'm on the Internet</TextBox>
<Button Grid.Row="0" Grid.Column="2">Don't click me</Button>
<Label Grid.Row="1" Grid.Column="0">Text2</Label>
<Slider Grid.Row="1" Grid.Column="1"></Slider>
<Button Grid.Row="1" Grid.Column="2">Click the other guy</Button>
</Grid>
</Window>
What I would like to have, without having to do it manually:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test" Width="300" Height="100">
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label VerticalAlignment="Center" Grid.Row="0" Grid.Column="0">Text</Label>
<TextBox VerticalAlignment="Center" Grid.Row="0" Grid.Column="1">I'm on the Internet</TextBox>
<Button VerticalAlignment="Center" Grid.Row="0" Grid.Column="2">Don't click me</Button>
<Label VerticalAlignment="Center" Grid.Row="1" Grid.Column="0">Text2</Label>
<Slider VerticalAlignment="Center" Grid.Row="1" Grid.Column="1"></Slider>
<Button VerticalAlignment="Center" Grid.Row="1" Grid.Column="2">Click the other guy</Button>
</Grid>
</Window>
Although I'm not really sure there was any difference here. It's not a deal breaker or anything, but I'd like to do it this way.
VisualTree inheritance is not universal. The dependency property specifies that it will inherit down the visual tree when it is declared. In this case, verticalalignment is not.
The only way to get a consistent vertical alignment is to use a style. And you can't use an implicit style across different types of controls. So you need to create a named style, place it in the resources of the container. Add a setter to the style to set the vertical alignment to whichever value you want. Finally reference the style in all the controls to which you want it applied.
Here is your example done with styles...unfortunately you're not saving much typing however if your style did something like Set VerticalAlignment and the FontFamily, then you're saving space...If you think of it like CSS then WPF Styles are easy.
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test" Width="300" Height="100">
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style x:Key="setVA" TargetType="{x:Type Control}">
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
</Grid.Resources>
<Label Style="{StaticResource setVA}" Grid.Row="0" Grid.Column="0">Text</Label>
<TextBox Style="{StaticResource setVA}" Grid.Row="0" Grid.Column="1">I'm on the Internet</TextBox>
<Button Style="{StaticResource setVA}" Grid.Row="0" Grid.Column="2">Don't click me</Button>
<Label Style="{StaticResource setVA}" Grid.Row="1" Grid.Column="0">Text2</Label>
<Slider Style="{StaticResource setVA}" Grid.Row="1" Grid.Column="1"></Slider>
<Button Style="{StaticResource setVA}" Grid.Row="1" Grid.Column="2">Click the other guy</Button>
</Grid>
</Window>
There's more information on using styles on MSDN

Resources