WPF Adorner Newbee - wpf

Using VB.Net & WPF
I'm Using Code Available at Overlaying Controls in WPF with Adorners (Converted to VB.Net)
MainWindow.xaml
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid Name="G1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Text=" This is Parent Control " HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Button Grid.Row="1" Content="Show Child Control " HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click"/>
</Grid>
</Window>
Code Behind
Class MainWindow
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
Dim U1 As New UserControl1
Using OverlayAdorner(Of UserControl).Overlay(G1, U1)
End Using
End Sub
End Class
UserControl1.xaml
UserControl x:Class="UserControl1"
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"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Background=" #44000000">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="1" Background="White" HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Text=" This is Child Control " HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5"/>
<TextBox Name="T1" Grid.Row="1" Margin="5"/>
<Button Grid.Row="2" Content="Close Child Control " HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click" Margin="5"/>
</Grid>
</Grid>
</UserControl>
Code Behind
Public Class UserControl1
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
End Sub
Public Property UserInput As String
Get
Return T1.Text
End Get
Set(value As String)
T1.Text = value
End Set
End Property
End Class
Now when user clicks on button in mainwindow, usercontrol1 should open as adorner and allow user to enter some text in textbox and when user clicks button in usercontrol1 it should close and return text to mainwindow where it would be displayed as message box.
Please Help me to achive the same as i'm newbie in wpf

I attempted to write a pure xaml based solution, you may adjust as per your needs
in this sample there are 2 textboxes 1st is regular while other popups a list when focused and allow you to select an item from it
sample code
<Grid>
<Grid.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Grid.Resources>
<StackPanel HorizontalAlignment="Center"
VerticalAlignment="Center"
MinWidth="200">
<TextBox Text="regular textbox" />
<TextBox Text="{Binding SelectedItem,ElementName=list,TargetNullValue=select an item}">
<TextBox.Triggers>
<EventTrigger RoutedEvent="GotFocus">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="button"
Storyboard.TargetProperty="IsChecked">
<DiscreteBooleanKeyFrame Value="true"
KeyTime="0:0:0" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBox.Triggers>
</TextBox>
</StackPanel>
<Border Background="#77000000"
Visibility="{Binding IsChecked,ElementName=button,Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="300"
Height="150">
<ListBox x:Name="list">
<sys:String>item 1</sys:String>
<sys:String>item 2</sys:String>
<sys:String>item 3</sys:String>
<sys:String>item 4</sys:String>
<ListBox.Triggers>
<EventTrigger RoutedEvent="MouseLeftButtonUp">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="button"
Storyboard.TargetProperty="IsChecked">
<DiscreteBooleanKeyFrame Value="False"
KeyTime="0:0:0" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ListBox.Triggers>
</ListBox>
<ToggleButton IsChecked="False"
x:Name="button"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Content="X"
ToolTip="Close" />
<Grid.Effect>
<DropShadowEffect Opacity=".5" />
</Grid.Effect>
</Grid>
</Border>
</Grid>
content of the grid inside the border is where you'll place your user control
just copy this code to a new project's main window and run it. give it a try and see if this is close to your needs, we can work out to fit it according to your needs.

Related

WPF Animation dependency issue

I just started to learn WPF and XAML and I tried to gete an animation sample to work on my machine. Basically, a label background should change when a specific value is set in the corresponding textbox.
Issue is I get the following error: Background' property does not point to a DependencyObject in path '(0).(1)
This is the XAML:
<Window x:Class="WpfDataBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:loc="clr-namespace:WpfDataBinding"
Title="MainWindow" Height="350" Width="264.828">
<Window.Resources>
<DataTemplate DataType="{x:Type loc:Person}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="210"/>
</Grid.ColumnDefinitions>
<TextBlock Name="nameLabel" Grid.Row="0" Grid.Column="0" Text="Name:" FontSize="14" Margin="3,3,0,0"/>
<TextBox Name="nameTextBox" Grid.Row="0" Grid.Column="1" Width="200" Text="{Binding Name}" FontSize="14" Margin="3" />
<TextBlock Name="ageLabel" Grid.Row="1" Grid.Column="0" Text="Age:" FontSize="14" Margin="3,3,0,0"/>
<TextBox Name="ageTextBox" Grid.Row="1" Grid.Column="1" Width="200" Text="{Binding Age}" FontSize="14" Margin="3"/>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Age}" Value="21">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="ageLabel"
Storyboard.TargetProperty="(Label.Background).(SolidColorBrush.Color)"
To="Red" Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Window.Resources>
<Grid Margin="0,0,0,-0.2" HorizontalAlignment="Left" Width="248">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListBox ItemsSource="{Binding}" />
<StackPanel Grid.Row="2" Grid.ColumnSpan="2">
<Button Content="_Show.." Click="Button_Click"/>
<Button Content="_Age" Click="Button_Click_1"/>
</StackPanel>
</Grid>
Thank you
In order to animate the Color property of a SolidColorBrush in the Background property of a UI Element, you need to first set the Background. The default value of the Background property of a TextBlock is null, so there is nothing to animate.
So, first set a Background before animating it:
<TextBlock ...>
<TextBlock.Background>
</SolidColorBrush Color="Transparent"/>
</TextBlock.Background>
</TextBlock>
Now your could write the TargetProperty path like
Storyboard.TargetProperty="Background.Color"
or
Storyboard.TargetProperty="(TextBlock.Background).Color"
or
Storyboard.TargetProperty="(TextBlock.Background).(SolidColorBrush.Color)"
or even
Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
All expressions are equivalent. The details are explained in the PropertyPath XAML Syntax article on MSDN.
As per this question you need to use:
ColorAnimation Storyboard.TargetName="ageLabel"
Storyboard.TargetProperty="(TextBlock.Background).Color"
To="Red" Duration="0:0:1"/>
rather than (TextBlock.Background).(SolidColorBrush.Color) as apparently Background and SolidColorBrush are the same object.
(Label.Background).(SolidColorBrush.Color) line is the problem. It needs to be <ColorAnimation Duration="0" To="Red" Storyboard.TargetProperty="(TextBlock.Background).(SolidColorBrush.Color)" Storyboard.TargetName="ageLabel" />

FluidMoveSetTagBehavior stretching Text vertically

I've recently start to learn all about FluidMoveSetTagBehavior and FluidMoveBehavior using Microsoft Expression Blend and Visual Studio 2010. Following a few examples I've found on the web, I've created the below sample which works well apart from a small problem.
I have been trying to test creating an animation to show an update of a TextBlock when a ListViewItem is selected.
When an item is selected in the ListView the text does move to the TextBlock as per the FluidMoveBehavior but the text is stretched vertically during the animation phase. It then snaps back correctly within the TextBlock once the animation ends. I initially had this problem with horizontal stretching too but I was able to solve this adding a few HorizontalAlignment="Left" properties. No such luck VerticalAlignment properties though.
Xaml Code
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<WrapPanel>
<TextBox Height="23" Name="TextBox1" Margin="4" VerticalAlignment="Center" Width="120" />
<Button Content="Add" Margin="4" Name="Button1" VerticalAlignment="Top" Width="75" />
<Button Content="Remove" Margin="4" Name="Button2" VerticalAlignment="Top" Width="75" />
</WrapPanel>
<ListView Grid.Row="1" Height="150" Name="ListView1" SelectionMode="Single" VerticalAlignment="Top">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel >
<i:Interaction.Behaviors>
<ei:FluidMoveBehavior Duration="0:0:0.5" AppliesTo="Children">
<ei:FluidMoveBehavior.EaseY>
<QuarticEase EasingMode="EaseInOut"/>
</ei:FluidMoveBehavior.EaseY>
<ei:FluidMoveBehavior.EaseX>
<QuarticEase EasingMode="EaseInOut"/>
</ei:FluidMoveBehavior.EaseX>
</ei:FluidMoveBehavior>
</i:Interaction.Behaviors>
</StackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontSize="14" HorizontalAlignment="Left" TextWrapping="Wrap"
Opacity="0" TextAlignment="Center" Height="23" >
<i:Interaction.Behaviors>
<ei:FluidMoveSetTagBehavior Tag="DataContext"/>
</i:Interaction.Behaviors>
<TextBlock.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Duration="00:00:01"
From="0"
To="1" BeginTime="00:00:00.4000000" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="FrameworkElement.Unloaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Duration="00:00:01"
From="1"
To="0" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StackPanel Grid.Column="1" Grid.Row="1">
<TextBlock DataContext="{Binding SelectedItem, Mode=TwoWay, ElementName=ListView1}" HorizontalAlignment="Left"
TextWrapping="Wrap" FontSize="14" Text="{Binding Mode=OneWay}" Height="23" >
<i:Interaction.Behaviors>
<ei:FluidMoveBehavior InitialTag="DataContext" Duration="0:0:2">
<ei:FluidMoveBehavior.EaseX>
<CircleEase EasingMode="EaseOut"/>
</ei:FluidMoveBehavior.EaseX>
</ei:FluidMoveBehavior>
</i:Interaction.Behaviors>
</TextBlock>
</StackPanel>
</Grid>
Code Behind
Class MainWindow
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
ListView1.Items.Insert(0, TextBox1.Text)
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button2.Click
ListView1.Items.Remove(ListView1.Items(0))
End Sub
End Class
Hope someone can help.

Trigger usercontrol storyboard from inner contentcontrol in wpf

I have two usercontrols:
Usercontrol 1:
- contains a storyboard animation in the usercontrol resources named "somestoryboard".
- contains a keyboard that has to be slide up when someone clicks on a textbox in usercontrol 2.
- contains a contentcontrol where any usercontrol dynamically resides.
Usercontrol 2:
- Contains a textbox with an eventtrigger. When touched the storyboard from usercontrol 1 has to be fired.
Unfortunately the whole binding goes wrong in the second user control. I constantly get the message "couldn't find object of storyboard".
How do I set this binding right in usercontrol 2, or is this even possible in purely xaml?
Here are the two usercontrols:
Usercontrol 1:
<UserControl (some namespaces)>
<UserControl.Resources>
<Storyboard x:Key="SomeControl">
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="aControl"
Storyboard.TargetProperty="Expanded" >
<DiscreteBooleanKeyFrame Value="True" KeyTime="0:0:0" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="500" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="800" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Grid.Column="1" Grid.Row="1" Background="{StaticResource DefaultBackground}" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition />
<RowDefinition Height="70" />
</Grid.RowDefinitions>
<ContentControl Grid.Row="1" Grid.Column="2" Margin="10,0,20,0" VerticalContentAlignment="Top"/>
</Grid>
<Controls:Somecontrol x:Name="aControl" VerticalAlignment="Bottom" Height="0" HorizontalAlignment="Stretch"
Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="1" Grid.RowSpan="2" UseAnimation="True"
Style="{StaticResource AnimatedControl}" />
</Grid>
Usercontrol 2:
<UserControl (some namespaces)>
<Grid Margin="5" >
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Text="{Binding InputMessage}" VerticalAlignment="Center" FontSize="12" Margin="0,0,0,5" />
<TextBox Grid.Row="1" Text="{Binding InputResult}" InnerBorderBrush="Blue" CornerRadius="5" Background="White" >
<TextBox .Triggers>
<EventTrigger RoutedEvent="TextBox.TouchUp">
<BeginStoryboard Storyboard="{StaticResource SomeControl}" />
</EventTrigger>
</TextBox.Triggers>
</TextBlock >
</Grid>
</UserControl>

How to call a Usercontrol from another in same window in WPF ?

I have two UserControls in my project's MainWindow. In MainWindow I call the first UserControl whose content is a Button and put this FirstControl in a Grid. How can I call the second UserControl when I click on the button in FirstUserControl in MainWindow?
First UserControl :
<UserControl x:Class="BenashManage.UserControl.ButtonUserControl"
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"
Height="auto" Width="auto" RenderTransformOrigin="0,0">
<Grid>
<Border x:Name="BorderAddEdit" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="5,5,5,5" CornerRadius="9,9,9,9" Background="{x:Null}">
<Grid Margin="0.2,0.2,5.4,4.2">
<Grid.RowDefinitions>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<Button Content="one" TextBlock.Foreground="White" Grid.Row="1" Margin="9,9,9,9" Height="28" TextBlock.FontSize="15" Name="btn_MartyMang" Click="click_Marty"/>
</Grid>
</Border>
</Grid>
</UserControl>
Second UserControl:
<UserControl x:Class="BenashManage.UserControl.InjuredUserControl"
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"
Height="auto" Width="auto"
mc:Ignorable="d" RenderTransformOrigin="0,0" FontFamily="Arial" FontSize="14" TextBlock.Foreground="White">
<Grid VerticalAlignment="Top" Height="auto" Width="360" HorizontalAlignment="Right">
<Border x:Name="BorderAddEdit" Margin="6,2,6,6" BorderThickness="5,5,5,5" CornerRadius="9,9,9,9" Background="{x:Null}">
<Grid VerticalAlignment="Center" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" MinHeight="20.8"/>
</Grid.ColumnDefinitions>
<TextBlock TextWrapping="Wrap" Text=":jjj" Grid.Column="1" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,4,-0.4,3"/>
<TextBox Grid.Row="6" TextAlignment="Right" VerticalAlignment="Center" Margin="3,2.8,2.2,2.2" />
</Grid>
</Border>
</Grid>
</UserControl>
MainWindow:
<Window x:Class="BenashManage.MartyrManage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:BenashManage.UserControl"
Title="MartyrManage" Height="550" Width="550" Style="{DynamicResource ModalWindowStyle}" Loaded="Window_Loaded_1">
<Window.CommandBindings>
<CommandBinding Command="Close"
Executed="CloseCommand_Executed"/>
</Window.CommandBindings>
<Grid >
<Grid Margin="179,10,10.4,10" HorizontalAlignment="Center" VerticalAlignment="Center"
*******
Height="456" Width="357" Name="MoveToUserControl" ></Grid>
<Grid Margin="10,71,372.4,67" HorizontalAlignment="Center" VerticalAlignment="Center" Height="338" Width="auto" Name="ButtonManage" >
<controls:FirstUserControl Margin="0,0,0,92">
</controls:FirstUserControl>
</Grid>
</Grid>
</Window>
There are a couple of ways you can do this:
1) Get the parent of the UserControl and then get its children.
(((control1).Parent as Panel).Children[1] as UserControl)
2) Raise an event in the one UserControl which is handled by MainWindow to call the function in the other UserControl.

MVVM + UserControl + UserControl + DependencyProperty

I have a user control which displays addresses housed inside of another page that is bound to a viewmodel. The viewmodel has a primitive User which has a collection of Address objects. The User control will reside on several pages so I would like to be able to bind it to the address list via a dependency property. While my current solution is working, something about it just doesn't feel right and I thought I'd ask for a second opinion. I have chopped out a lot of code for brevity's sake.
Basically the page binds to the dependency property in the usercontrols code behind which then updates the usercontrol's datagrid by setting it's itemsource. This seems to me to break the basic tenants of MVVM.
AddressListView control:
<UserControl x:Class="Insight.Controls.AddressListView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:tk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
xmlns:command="clr-namespace:PrismFramework.Implementors.Commanding;assembly=PrismFramework"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="840">
<UserControl.Resources>
<command:ObservableCommand x:Name="EditAddressCommand" Value="{Binding EditAddressCmd}"/>
<command:ObservableCommand x:Name="DeleteAddressCommand" Value="{Binding DeleteAddressCmd}"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<sdk:DataGrid Name="dgAddresses"
Height="Auto"
Width="Auto"
AutoGenerateColumns="False"
HeadersVisibility="None" >
<sdk:DataGrid.Columns>
<sdk:DataGridTemplateColumn x:Name="dgcAddresses"
Width="*" >
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Border x:Name="bdrAddress"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="Auto"
Width="Auto"
BorderBrush="Silver"
BorderThickness="1"
Padding="0"
Margin="1,1,1,1">
<Grid x:Name="grdAddressItem"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="Auto"
Width="Auto">
<Grid.RowDefinitions>
<RowDefinition Height="17" MinHeight="17"/>
<RowDefinition Height="17" MinHeight="17"/>
<RowDefinition Height="17" MinHeight="17"/>
<RowDefinition Height="17" MinHeight="17"/>
<RowDefinition Height="17" MinHeight="17"/>
<RowDefinition Height="17" MinHeight="17"/>
<RowDefinition Height="17" MinHeight="17"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="55" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Padding="0,0,5,0" Text="Type:" TextAlignment="Right" />
<TextBlock Grid.Column="1" Padding="0" Text="{Binding Path=AType}" Grid.ColumnSpan="2" />
<TextBlock Grid.Row ="1" Grid.Column="0" Padding="0,0,5,0" Text="Address 1:" TextAlignment="Right" />
<!-- List Of Similar Fields ->
<Grid x:Name="grdAddressEditOptions"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="Auto"
Width="Auto"
Grid.Column="3"
Grid.RowSpan="7" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button x:Name="btnEdit"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="Auto"
Width="Auto"
Grid.Row="0"
Padding="4,5,4,8"
Margin="0,8,10,0"
Command="{Binding Value, Source={StaticResource EditAddressCommand}}"
CommandParameter="{Binding}" >
<Button.Content>
<Image x:Name="btnEditIcon"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Height="Auto"
Width="Auto"
Source="/Insight.ModuleUser;component/Images/edit.png"
Visibility="Visible" />
</Button.Content>
</Button>
<Button x:Name="btnDelete"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="Auto"
Width="Auto"
Grid.Row="2"
Padding="4,5,4,8"
Margin="0,0,10,5"
Command="{Binding Value, Source={StaticResource DeleteAddressCommand}}"
CommandParameter="{Binding}" >
<Button.Content>
<Image x:Name="btnDeleteIcon"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Height="Auto"
Width="Auto"
Source="/Insight.ModuleUser;component/Images/delete.png"
Visibility="Visible" />
</Button.Content>
</Button>
</Grid>
</Grid>
</Border>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</Grid>
</UserControl>
AddressListView code behind:
Imports System.Collections.ObjectModel
Imports Insight.DataServices.Primitives
Partial Public Class AddressListView
Inherits UserControl
Public ReadOnly AddressesProperty As DependencyProperty = DependencyProperty.Register("Addresses", GetType(ObservableCollection(Of Address)), GetType(AddressListView), New PropertyMetadata(Nothing, New PropertyChangedCallback(AddressOf OnAddressesChanged)))
Public Sub New()
InitializeComponent()
End Sub
Public Property Addresses As ObservableCollection(Of Address)
Get
Return DirectCast(GetValue(AddressesProperty), ObservableCollection(Of Address))
End Get
Set(value As ObservableCollection(Of Address))
SetValue(AddressesProperty, value)
End Set
End Property
Public Sub OnAddressesChanged()
Me.dgAddresses.ItemsSource = Addresses
End Sub
End Class
Base page:
<UserControl x:Class="Insight.ModuleUser.Views.EditUserView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:prism="clr-namespace:Microsoft.Practices.Prism.Interactivity.InteractionRequest;assembly=Microsoft.Practices.Prism.Interactivity"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cm="clr-namespace:System.ComponentModel;assembly=System.Windows"
xmlns:data="clr-namespace:System.Windows.Data;assembly=System.Windows"
xmlns:vm="clr-namespace:Insight.ModuleUser.ViewModels"
xmlns:command="clr-namespace:PrismFramework.Implementors.Commanding;assembly=PrismFramework"
xmlns:controls="clr-namespace:Insight.Controls;assembly=Insight.Controls"
xmlns:modalDialogs="clr-namespace:Insight.Controls.ModalDialogViews;assembly=Insight.Controls"
mc:Ignorable="d"
d:DesignHeight="500" d:DesignWidth="1144"
d:DataContext="{d:DesignData /Insight.ModuleUser;component/SampleData/EditUserViewModelSampleData.xaml}">
<UserControl.Resources>
<command:ObservableCommand x:Name="OpenProjectCommand" Value="{Binding OpenProjectCmd}"/>
<command:ObservableCommand x:Name="OpenPaymentCommand" Value="{Binding OpenPaymentCmd}"/>
<command:ObservableCommand x:Name="OpenInvoiceCommand" Value="{Binding OpenInvoiceCmd}"/>
<command:ObservableCommand x:Name="OpenPaymentItemCommand" Value="{Binding OpenPaymentItemCmd}"/>
<command:ObservableCommand x:Name="EditPhoneCommand" Value="{Binding EditPhoneNumberCmd}"/>
<command:ObservableCommand x:Name="DeletePhoneCommand" Value="{Binding DeletePhoneNumberCmd}"/>
<command:ObservableCommand x:Name="EditEmailAddressCommand" Value="{Binding EditEmailAddressCmd}"/>
<command:ObservableCommand x:Name="DeleteEmailAddressCommand" Value="{Binding DeleteEmailAddressCmd}"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" >
<controls:AddressListView x:Name="ctrlAddressListView"
Addresses="{Binding User.Addresses}" />
</Grid>
</UserControl>
This seems a perfectly reasonable approach. However, you could use binding in your user control view, rather than setting the items source in code.
To do this you need to set the DataContext of the user control to be your user control type. This could be done either in the code behind for the user control (setting this.DataContext = this), or through element binding in XAML:
<UserControl
...
x:Name="MyName"
DataContext="{Binding ElementName=MyName}"
However, my approach would be not to use a user control at all, as all you're really talking about is view composition and reusing a particular section of the view between other views.
View composition is extremely straightforward with an MVVM framework such as Caliburn.Micro. In this case you would have an AddressViewModel and AddressView, and use a ContentControl to inject the AddressView into the base view:
<ContentControl x:Name="AddressViewModel" />

Resources