Ask a questionAsk a question
 

AnswerTextbox not updating binding when focus lost.

  • Wednesday, November 04, 2009 8:07 PMJesper Odgaard Nielsen Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    On a tabcontrol I have several tabpages, on each tab page there is a textbox. This textbox is content bound with a simple Path=Foo and navigates to the Foo property of the ViewModel through datacontext setting on the view. I.e. mvvm setup. Now, when I enter something in the textbox, and click on another tab page, the text in the text box is discarded instead of being updated as focus leaves the textbox. Only if I place something else on the same tab page that can recieve focus, the textbox is correctly updating the viewmodel when focus is lost. Any ideas why textbox dont trigger LostFocus when changing tab page?

    Another thing, is it possible to update bindings in a textbox explicit when e.g. the enter key is pressed? Is it possible from xaml alone?
    Best regards Jesper Odgaard Nielsen

Answers

  • Thursday, November 12, 2009 7:27 AMhbarck Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    Hi,

    here is a Submit Sticky Command:

    Namespace Validation
        Public Class Submit
            Inherits DependencyObject
    
            Public Shared ReadOnly CommandProperty As DependencyProperty = DependencyProperty.RegisterAttached("Command", GetType(RoutedCommand), GetType(Submit), New PropertyMetadata(AddressOf OnCommandChanged))
            Public Shared Function GetCommand(ByVal d As DependencyObject) As RoutedCommand
                Return d.GetValue(CommandProperty)
            End Function
            Public Shared Sub SetCommand(ByVal d As DependencyObject, ByVal value As RoutedCommand)
                d.SetValue(CommandProperty, value)
            End Sub
            Private Shared Sub OnCommandChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
                Dim f As FrameworkElement = TryCast(d, FrameworkElement)
                If f IsNot Nothing Then
                    If e.OldValue IsNot Nothing Then
                        Detach(f, e.OldValue)
                    End If
                    If e.NewValue IsNot Nothing Then
                        Attach(f, e.NewValue)
                    End If
                End If
            End Sub
    
            Public Shared ReadOnly KeyGestureProperty As DependencyProperty = DependencyProperty.RegisterAttached("KeyGesture", GetType(KeyGesture), GetType(Submit), New PropertyMetadata(AddressOf OnKeyGestureChanged))
            Public Shared Function GetKeyGesture(ByVal d As DependencyObject) As KeyGesture
                Return d.GetValue(KeyGestureProperty)
            End Function
            Public Shared Sub SetKeyGesture(ByVal d As DependencyObject, ByVal value As KeyGesture)
                d.SetValue(KeyGestureProperty, value)
            End Sub
            Private Shared Sub OnKeyGestureChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
                Dim f As FrameworkElement = TryCast(d, FrameworkElement)
                If f IsNot Nothing Then
                    If e.OldValue IsNot Nothing Then
                        DetachKeyGesture(f)
                    End If
                    If e.NewValue IsNot Nothing Then
                        AttachKeyGesture(f, GetCommand(f), e.NewValue)
                    End If
                End If
            End Sub
    
            Private Shared Sub Attach(ByVal d As FrameworkElement, ByVal command As RoutedCommand)
                d.CommandBindings.Add(New SubmitCommandBinding(command))
                Dim gesture As KeyGesture = GetKeyGesture(d)
                AttachKeyGesture(d, command, gesture)
                If d.BindingGroup Is Nothing Then
                    d.BindingGroup = New BindingGroup
                End If
            End Sub
    
            Private Shared Sub AttachKeyGesture(ByVal d As FrameworkElement, ByVal command As RoutedCommand, ByVal gesture As KeyGesture)
                ' Can only attach a KeyGesture when both the gesture and the command have been set.
                If command IsNot Nothing And gesture IsNot Nothing Then
                    d.InputBindings.Add(New SubmitInputBinding(command, gesture))
                End If
            End Sub
            Private Shared Sub Detach(ByVal d As FrameworkElement, ByVal command As RoutedCommand)
                ' Use the type if the CommandBinding to find the sticky binding without storing a reference to it
                For Each b As SubmitCommandBinding In d.CommandBindings.OfType(Of SubmitCommandBinding)()
                    d.CommandBindings.Remove(b)
                Next
                DetachKeyGesture(d)
            End Sub
            Private Shared Sub DetachKeyGesture(ByVal d As FrameworkElement)
                ' Use the type of the InputBinding to find the sticky binding without storing a reference to it
                For Each i As SubmitInputBinding In d.InputBindings.OfType(Of SubmitInputBinding)()
                    d.InputBindings.Remove(i)
                Next
            End Sub
    
    
            Private Shared Sub OnCanExecuteSubmit(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)
    
                Dim result As Boolean = False
                Dim target As FrameworkElement = TryCast(sender, FrameworkElement)
                If target IsNot Nothing Then
                    ' Separate event specific code from domain specific code...
                    result = CanExecuteSubmit(target)
                End If
                e.CanExecute = result
                e.Handled = True
            End Sub
    
            ''' <summary>
            ''' Contains the logic that checks whether the command can be executed
            ''' </summary>
            ''' <param name="target"></param>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Private Shared Function CanExecuteSubmit(ByVal target As FrameworkElement) As Boolean
                Dim result As Boolean = False
                If target IsNot Nothing Then
                    result = (target.BindingGroup IsNot Nothing AndAlso Not System.Windows.Controls.Validation.GetHasError(target))
                End If
                Return result
            End Function
    
            Private Shared Sub OnExecutedSubmit(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)
                Dim target As FrameworkElement = TryCast(sender, FrameworkElement)
                If target IsNot Nothing Then
                    If CanExecuteSubmit(target) Then
                        ExecuteSubmit(target)
                    End If
                    e.Handled = True
                End If
            End Sub
    
    
            ''' <summary>
            ''' Contains the logic that executes the command...
            ''' </summary>
            ''' <param name="target"></param>
            ''' <remarks></remarks>
            Private Shared Sub ExecuteSubmit(ByVal target As FrameworkElement)
                target.BindingGroup.UpdateSources()
            End Sub
    
            ''' <summary>
            ''' Dummy class in order to mark CommandBindings that have been set up through this sticky
            ''' command with their type.
            ''' </summary>
            ''' <remarks></remarks>
            Public Class SubmitCommandBinding
                Inherits CommandBinding
                Public Sub New(ByVal command As RoutedCommand)
                    MyBase.New(command, AddressOf OnExecutedSubmit, AddressOf OnCanExecuteSubmit)
                End Sub
            End Class
    
            ''' <summary>
            ''' Dummy class in order to mark InputBindings that have been set up through this sticky
            ''' command with their type.
            ''' </summary>
            ''' <remarks></remarks>
            Public Class SubmitInputBinding
                Inherits InputBinding
                Public Sub New(ByVal command As RoutedCommand, ByVal gesture As InputGesture)
                    MyBase.New(command, gesture)
                End Sub
            End Class
        End Class
    End Namespace
    
    

    And this is how you use it:

    <Window x:Class="SubmitCommandWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ex="clr-namespace:WpfGlueExamples"
        xmlns:v="http://wpfglue.wordpress.com/validation"
        Title="SubmitCommandWindow">
        <Window.Resources>
            <ex:Customer x:Key="data"/>
            <RoutedCommand x:Key="SubmitCommand"/>
        </Window.Resources>
        <StackPanel DataContext="{StaticResource data}">
        <!-- CustomerGroupBox is the base for the SubmitCommand Sticky Command. 
            All controls inside this container will connect the Enter key with the SubmitCommand.
            Because Submit.Command sets CustomerGroupBox.BindingGroup automatically, 
            the UpdateSourceTrigger for all controls will be changed to Explicit, 
            and they will update their sources together when the SubmitCommand is invoked.
            
            All Buttons inside this container will be able to send out the SubmitCommand
            without a CommandTarget parameter.-->
        <GroupBox x:Name="CustomerGroupBox" Header="Customer" v:Submit.Command="{StaticResource SubmitCommand}" v:Submit.KeyGesture="Enter">
                <Grid>
                    <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Label Grid.Row="0">Name</Label>
                <Label Grid.Row="1">Address</Label>
                <Label Grid.Row="2">City</Label>
                <Label Grid.Row="3">Country</Label>
                    <TextBox x:Name="NameTextBox" Grid.Column="1" Grid.Row="0" Text="{Binding Name}"/>
                    <TextBox x:Name="AddressTextBox" Grid.Column="1" Grid.Row="1" Text="{Binding Address}"/>
                <TextBox x:Name="CityTextBox" Grid.Column="1" Grid.Row="2" Text="{Binding City}"/>
                <TextBox x:Name="CountryTextBox" Grid.Column="1" Grid.Row="3" Text="{Binding Country}"/>
                    <Button Command="{StaticResource SubmitCommand}" Grid.Row="4">Submit</Button>
    
                </Grid>
        </GroupBox>
    
            <GroupBox Header="Customer Data">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Label Grid.Row="0">Name</Label>
                    <Label Grid.Row="1">Address</Label>
                    <Label Grid.Row="2">City</Label>
                    <Label Grid.Row="3">Country</Label>
                    <TextBlock x:Name="NameTextBlock" Grid.Column="1" Grid.Row="0" Text="{Binding Name}"/>
                    <TextBlock x:Name="AddressTextBlock" Grid.Column="1" Grid.Row="1" Text="{Binding Address}"/>
                    <TextBlock x:Name="CityTextBlock" Grid.Column="1" Grid.Row="2" Text="{Binding City}"/>
                    <TextBlock x:Name="CountryTextBlock" Grid.Column="1" Grid.Row="3" Text="{Binding Country}"/>
                </Grid>
            </GroupBox>
            <!-- This Button invokes the SubmitCommand on the CustomerGroupBox 
                 directly by setting it as CommandTarget.-->
            <Button Command="{StaticResource SubmitCommand}" CommandTarget="{Binding ElementName=CustomerGroupBox}">Submit</Button>
        </StackPanel>
    </Window>
    
    

    If you want to run the example, you'll also need this example class:

    Public Class Customer
        Implements System.ComponentModel.INotifyPropertyChanged
    
        Protected Overridable Sub OnPropertyChanged(ByVal ParamArray propertynames() As String)
            If propertynames.Length = 0 Then
                RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(""))
            Else
    
                For Each propertyName As String In propertynames
                    RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(propertyName))
                Next
            End If
        End Sub
    
        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    
        Private _Name As String
        Private _Address As String
        Private _City As String
        Private _Country As String
    
        Public Property Name() As String
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
                OnPropertyChanged("Name")
            End Set
        End Property
    
        Public Property Address() As String
            Get
                Return _Address
            End Get
            Set(ByVal value As String)
                _Address = value
                OnPropertyChanged("Address")
            End Set
        End Property
        Public Property City() As String
            Get
                Return _City
            End Get
            Set(ByVal value As String)
                _City = value
                OnPropertyChanged("City")
            End Set
        End Property
        Public Property Country() As String
            Get
                Return _Country
            End Get
            Set(ByVal value As String)
                _Country = value
                OnPropertyChanged("Country")
            End Set
        End Property
    End Class
    
    



    http://wpfglue.wordpress.com

All Replies

  • Wednesday, November 04, 2009 8:42 PMFoovanadil Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Not sure why the binding is being thrown away when tab is switched. Maybe there is some UI virutlization going on that is breaking the UpdateSourceTrigger setting for textbox.

    By default the binding's UpdateSourceTrigger is set to LostFocus for TextBoxes, you could override that and set it to PropertyChanged which will cause your binding to update on every keystroke (might not be exactly what you want)


  • Wednesday, November 04, 2009 8:44 PMdmikon Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Can you try setting the Focusable property to true on your TabItems? Perhaps switching tabs by default is not considered a loss of focus (if they're not focusable).
  • Tuesday, November 10, 2009 11:57 AMZhi-Xin YeMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi Jesper,

    Could you post some code to show how your TabControl is defined?

    Best Regards,
    Zhi-Xin


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework!
  • Tuesday, November 10, 2009 2:55 PMhbarck Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi,

    this is about the second part of the question, regarding a way to make a binding update itself when Enter is pressed, and doing this in XAML.

    Well, the answer is yes and no: no, you can't do it right away in XAML, but yes, you can formulate your code so that you can use it through XAML wherever you want.

    This would be a simple job for a Sticky Command. A sticky command is a design pattern where setting an attached property on an element in XAML registers a CommandBinding with the element. You have to implement the attached property and the code that handles the command in code, but once you have it, you can use the attached property wherever you want in XAML, e.g. in a Style, which would enable you to add commands to controls without subclassing.

    In your special case, you'd have to do the following:
    1. Define a shared RoutedCommand instance as reference for the update command
    2. Implement an attached property. You could use a Boolean, in order to switch the ability to handle the command on and of by setting it to true or false
    3. In the PropertyChangedHandler of the attached property, if NewValue is true, add a new CommandBinding for the update command, binding its CanExecute and Executed handlers to two static (shared) methods defined in the class that provides the attached property. You might want to store this CommandBinding in a static (shared) variable of the class, so that you can reuse it. Add this CommandBinding to the CommandBindings collection of the element the attached property is set on. If OldValue is true, remove the commandbinding from the CommandBindings collection.
    4. In the implementation of the Executed handler, find the BindingGroup of the element on which the property is declared, and call its UpdateSources method. Using a BindingGroup here has the advantage that you can update a set of related controls at the same time, that it is easier to find out what bindings need to be updated, and that the UpdateSourceTrigger for all controls in the group will be set to Explicit automatically. (If you can't use a BindingGroup, you will have to find a way to tell the command implementation what binding on what property you are interested in, so you can call the UpdateSource method on the binding).
    5. Create an InputBinding for the update command, connecting it to the Enter key. Then if you press enter in the correct group, the RoutedCommand mechanism should automatically detect the commandbinding that is able to handle the command and update all the controls in the group.

    This would be a typical piece of WPFGlue. If you give me some time, I'll probably post an implementation in VB.
    http://wpfglue.wordpress.com
  • Thursday, November 12, 2009 7:27 AMhbarck Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    Hi,

    here is a Submit Sticky Command:

    Namespace Validation
        Public Class Submit
            Inherits DependencyObject
    
            Public Shared ReadOnly CommandProperty As DependencyProperty = DependencyProperty.RegisterAttached("Command", GetType(RoutedCommand), GetType(Submit), New PropertyMetadata(AddressOf OnCommandChanged))
            Public Shared Function GetCommand(ByVal d As DependencyObject) As RoutedCommand
                Return d.GetValue(CommandProperty)
            End Function
            Public Shared Sub SetCommand(ByVal d As DependencyObject, ByVal value As RoutedCommand)
                d.SetValue(CommandProperty, value)
            End Sub
            Private Shared Sub OnCommandChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
                Dim f As FrameworkElement = TryCast(d, FrameworkElement)
                If f IsNot Nothing Then
                    If e.OldValue IsNot Nothing Then
                        Detach(f, e.OldValue)
                    End If
                    If e.NewValue IsNot Nothing Then
                        Attach(f, e.NewValue)
                    End If
                End If
            End Sub
    
            Public Shared ReadOnly KeyGestureProperty As DependencyProperty = DependencyProperty.RegisterAttached("KeyGesture", GetType(KeyGesture), GetType(Submit), New PropertyMetadata(AddressOf OnKeyGestureChanged))
            Public Shared Function GetKeyGesture(ByVal d As DependencyObject) As KeyGesture
                Return d.GetValue(KeyGestureProperty)
            End Function
            Public Shared Sub SetKeyGesture(ByVal d As DependencyObject, ByVal value As KeyGesture)
                d.SetValue(KeyGestureProperty, value)
            End Sub
            Private Shared Sub OnKeyGestureChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
                Dim f As FrameworkElement = TryCast(d, FrameworkElement)
                If f IsNot Nothing Then
                    If e.OldValue IsNot Nothing Then
                        DetachKeyGesture(f)
                    End If
                    If e.NewValue IsNot Nothing Then
                        AttachKeyGesture(f, GetCommand(f), e.NewValue)
                    End If
                End If
            End Sub
    
            Private Shared Sub Attach(ByVal d As FrameworkElement, ByVal command As RoutedCommand)
                d.CommandBindings.Add(New SubmitCommandBinding(command))
                Dim gesture As KeyGesture = GetKeyGesture(d)
                AttachKeyGesture(d, command, gesture)
                If d.BindingGroup Is Nothing Then
                    d.BindingGroup = New BindingGroup
                End If
            End Sub
    
            Private Shared Sub AttachKeyGesture(ByVal d As FrameworkElement, ByVal command As RoutedCommand, ByVal gesture As KeyGesture)
                ' Can only attach a KeyGesture when both the gesture and the command have been set.
                If command IsNot Nothing And gesture IsNot Nothing Then
                    d.InputBindings.Add(New SubmitInputBinding(command, gesture))
                End If
            End Sub
            Private Shared Sub Detach(ByVal d As FrameworkElement, ByVal command As RoutedCommand)
                ' Use the type if the CommandBinding to find the sticky binding without storing a reference to it
                For Each b As SubmitCommandBinding In d.CommandBindings.OfType(Of SubmitCommandBinding)()
                    d.CommandBindings.Remove(b)
                Next
                DetachKeyGesture(d)
            End Sub
            Private Shared Sub DetachKeyGesture(ByVal d As FrameworkElement)
                ' Use the type of the InputBinding to find the sticky binding without storing a reference to it
                For Each i As SubmitInputBinding In d.InputBindings.OfType(Of SubmitInputBinding)()
                    d.InputBindings.Remove(i)
                Next
            End Sub
    
    
            Private Shared Sub OnCanExecuteSubmit(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)
    
                Dim result As Boolean = False
                Dim target As FrameworkElement = TryCast(sender, FrameworkElement)
                If target IsNot Nothing Then
                    ' Separate event specific code from domain specific code...
                    result = CanExecuteSubmit(target)
                End If
                e.CanExecute = result
                e.Handled = True
            End Sub
    
            ''' <summary>
            ''' Contains the logic that checks whether the command can be executed
            ''' </summary>
            ''' <param name="target"></param>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Private Shared Function CanExecuteSubmit(ByVal target As FrameworkElement) As Boolean
                Dim result As Boolean = False
                If target IsNot Nothing Then
                    result = (target.BindingGroup IsNot Nothing AndAlso Not System.Windows.Controls.Validation.GetHasError(target))
                End If
                Return result
            End Function
    
            Private Shared Sub OnExecutedSubmit(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)
                Dim target As FrameworkElement = TryCast(sender, FrameworkElement)
                If target IsNot Nothing Then
                    If CanExecuteSubmit(target) Then
                        ExecuteSubmit(target)
                    End If
                    e.Handled = True
                End If
            End Sub
    
    
            ''' <summary>
            ''' Contains the logic that executes the command...
            ''' </summary>
            ''' <param name="target"></param>
            ''' <remarks></remarks>
            Private Shared Sub ExecuteSubmit(ByVal target As FrameworkElement)
                target.BindingGroup.UpdateSources()
            End Sub
    
            ''' <summary>
            ''' Dummy class in order to mark CommandBindings that have been set up through this sticky
            ''' command with their type.
            ''' </summary>
            ''' <remarks></remarks>
            Public Class SubmitCommandBinding
                Inherits CommandBinding
                Public Sub New(ByVal command As RoutedCommand)
                    MyBase.New(command, AddressOf OnExecutedSubmit, AddressOf OnCanExecuteSubmit)
                End Sub
            End Class
    
            ''' <summary>
            ''' Dummy class in order to mark InputBindings that have been set up through this sticky
            ''' command with their type.
            ''' </summary>
            ''' <remarks></remarks>
            Public Class SubmitInputBinding
                Inherits InputBinding
                Public Sub New(ByVal command As RoutedCommand, ByVal gesture As InputGesture)
                    MyBase.New(command, gesture)
                End Sub
            End Class
        End Class
    End Namespace
    
    

    And this is how you use it:

    <Window x:Class="SubmitCommandWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ex="clr-namespace:WpfGlueExamples"
        xmlns:v="http://wpfglue.wordpress.com/validation"
        Title="SubmitCommandWindow">
        <Window.Resources>
            <ex:Customer x:Key="data"/>
            <RoutedCommand x:Key="SubmitCommand"/>
        </Window.Resources>
        <StackPanel DataContext="{StaticResource data}">
        <!-- CustomerGroupBox is the base for the SubmitCommand Sticky Command. 
            All controls inside this container will connect the Enter key with the SubmitCommand.
            Because Submit.Command sets CustomerGroupBox.BindingGroup automatically, 
            the UpdateSourceTrigger for all controls will be changed to Explicit, 
            and they will update their sources together when the SubmitCommand is invoked.
            
            All Buttons inside this container will be able to send out the SubmitCommand
            without a CommandTarget parameter.-->
        <GroupBox x:Name="CustomerGroupBox" Header="Customer" v:Submit.Command="{StaticResource SubmitCommand}" v:Submit.KeyGesture="Enter">
                <Grid>
                    <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Label Grid.Row="0">Name</Label>
                <Label Grid.Row="1">Address</Label>
                <Label Grid.Row="2">City</Label>
                <Label Grid.Row="3">Country</Label>
                    <TextBox x:Name="NameTextBox" Grid.Column="1" Grid.Row="0" Text="{Binding Name}"/>
                    <TextBox x:Name="AddressTextBox" Grid.Column="1" Grid.Row="1" Text="{Binding Address}"/>
                <TextBox x:Name="CityTextBox" Grid.Column="1" Grid.Row="2" Text="{Binding City}"/>
                <TextBox x:Name="CountryTextBox" Grid.Column="1" Grid.Row="3" Text="{Binding Country}"/>
                    <Button Command="{StaticResource SubmitCommand}" Grid.Row="4">Submit</Button>
    
                </Grid>
        </GroupBox>
    
            <GroupBox Header="Customer Data">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Label Grid.Row="0">Name</Label>
                    <Label Grid.Row="1">Address</Label>
                    <Label Grid.Row="2">City</Label>
                    <Label Grid.Row="3">Country</Label>
                    <TextBlock x:Name="NameTextBlock" Grid.Column="1" Grid.Row="0" Text="{Binding Name}"/>
                    <TextBlock x:Name="AddressTextBlock" Grid.Column="1" Grid.Row="1" Text="{Binding Address}"/>
                    <TextBlock x:Name="CityTextBlock" Grid.Column="1" Grid.Row="2" Text="{Binding City}"/>
                    <TextBlock x:Name="CountryTextBlock" Grid.Column="1" Grid.Row="3" Text="{Binding Country}"/>
                </Grid>
            </GroupBox>
            <!-- This Button invokes the SubmitCommand on the CustomerGroupBox 
                 directly by setting it as CommandTarget.-->
            <Button Command="{StaticResource SubmitCommand}" CommandTarget="{Binding ElementName=CustomerGroupBox}">Submit</Button>
        </StackPanel>
    </Window>
    
    

    If you want to run the example, you'll also need this example class:

    Public Class Customer
        Implements System.ComponentModel.INotifyPropertyChanged
    
        Protected Overridable Sub OnPropertyChanged(ByVal ParamArray propertynames() As String)
            If propertynames.Length = 0 Then
                RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(""))
            Else
    
                For Each propertyName As String In propertynames
                    RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(propertyName))
                Next
            End If
        End Sub
    
        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    
        Private _Name As String
        Private _Address As String
        Private _City As String
        Private _Country As String
    
        Public Property Name() As String
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
                OnPropertyChanged("Name")
            End Set
        End Property
    
        Public Property Address() As String
            Get
                Return _Address
            End Get
            Set(ByVal value As String)
                _Address = value
                OnPropertyChanged("Address")
            End Set
        End Property
        Public Property City() As String
            Get
                Return _City
            End Get
            Set(ByVal value As String)
                _City = value
                OnPropertyChanged("City")
            End Set
        End Property
        Public Property Country() As String
            Get
                Return _Country
            End Get
            Set(ByVal value As String)
                _Country = value
                OnPropertyChanged("Country")
            End Set
        End Property
    End Class
    
    



    http://wpfglue.wordpress.com
  • Thursday, November 19, 2009 5:36 AMZhi-Xin YeMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi Jesper,

    How about the issue now? Do you still need help on this issue? If you have any questions or concerns, please feel free to let me know.

    Best Regards,
    Zhi-Xin


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework!