views:

200

answers:

1

I'm using a the WPF DataGrid from the wpf toolkit and a TimePicker from AvalonControlsLibrary to insert a collection of TimeSpans. My problem is that bindings are not working inside the DataGrid, and I have no clue of why this isn't working.

Here is my setup:

I have the following XAML:

<Window x:Class="TestMainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:wpf="http://schemas.microsoft.com/wpf/2008/toolkit" xmlns:a="http://schemas.AvalonControls/AvalonControlsLibrary/Controls" SizeToContent="WidthAndHeight" MinHeight="250" MinWidth="300">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <GroupBox Grid.Row="0">
        <GroupBox.Header>
            Testing it:
        </GroupBox.Header>
        <wpf:DataGrid ItemsSource="{Binding Path=TestSpans}" AutoGenerateColumns="False">
            <wpf:DataGrid.Columns>
                <wpf:DataGridTemplateColumn Header="Start">
                    <wpf:DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <a:TimePicker SelectedTime="{Binding Path=Span, Mode=TwoWay}" />
                        </DataTemplate>
                    </wpf:DataGridTemplateColumn.CellEditingTemplate>
                    <wpf:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Path=Span}" />
                        </DataTemplate>
                    </wpf:DataGridTemplateColumn.CellTemplate>
                </wpf:DataGridTemplateColumn>
            </wpf:DataGrid.Columns>
        </wpf:DataGrid>
    </GroupBox>
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="1">
        <a:TimePicker SelectedTime="{Binding Path=SelectedTime, Mode=TwoWay}" />
    </StackPanel>
</Grid>

And this is my ViewModel:

Imports System.Collections.ObjectModel

Public Class TestMainWindowViewModel

    Private _selectedTime As TimeSpan = DateTime.Now.TimeOfDay
    Public Property SelectedTime() As TimeSpan
        Get
            Return _selectedTime
        End Get
        Set(ByVal value As TimeSpan)
            _selectedTime = value
        End Set
    End Property

    Private _testSpans As ObservableCollection(Of TimeSpanContainer) = New ObservableCollection(Of TimeSpanContainer)
    Public Property TestSpans() As ObservableCollection(Of TimeSpanContainer)
        Get
            Return _testSpans
        End Get
        Set(ByVal value As ObservableCollection(Of TimeSpanContainer))
            _testSpans = value
        End Set
    End Property

    Public Sub New()
        _testSpans.Add(DateTime.Now.TimeOfDay)
        _testSpans.Add(DateTime.Now.TimeOfDay)
        _testSpans.Add(DateTime.Now.TimeOfDay)
    End Sub

End Class

Public Class TimeSpanContainer

    Private _span As TimeSpan
    Public Property Span() As TimeSpan
        Get
            Return _span
        End Get
        Set(ByVal value As TimeSpan)
            _span = value
        End Set
    End Property

    Public Sub New(ByVal t As TimeSpan)
        _span = t
    End Sub

End Class

I'm starting this window in application.xaml.vb like this:

Class Application

    ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException
    ' can be handled in this file.
    Protected Overrides Sub OnStartup(ByVal e As System.Windows.StartupEventArgs)
        MyBase.OnStartup(e)
        Dim window As TestMainWindow = New TestMainWindow

        window.DataContext = New TestMainWindowViewModel()

        window.Show()

    End Sub

End Class

EDIT 1: I forgot to mention that the binding to SelectedTime TimeSpan works as expected. The problem are the bindings inside the DataGrid.

EDIT 2: Changed example a little bit to show the problem better.

A: 

Hi, What do you mean by your bindings aren't working? Are you getting no value in the timepicker control when you attempt to edit the value?

Edit:

Ok, I was having this same issue yesterday and I think there is 2 parts to the issue.

  1. If there is no value appearing in the TimePicker control when you switch to edit mode then there is probably a binding issue with the control.

  2. The binding to the underlying value I found to be an issue with using the DataGridTemplateColumn. Basically the grid doesnt handle your databinding back using the same mechanisms of regular bound columns. What it means is you need to perform the following binding on your controls within the column:

    SelectedTime="{Binding Span, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

This will fix the binding back to the underlying object. However if there is still an issue with the control it may not help you much. Sorry but I haven't used AvalonControlsLibrary so not sure if there is a potential problem there. Fixing step 2 solved my issues.

Cheers

-Leigh

Leigh Shayler
Yeah, that's right. When I enter edit mode, the value of the timepicker control is set to the current time and when I'm done editing the value on the textblock is the same as before, so the value of the TimeSpanContainer.Span I'm editing never changes.
Jorge Vargas
I'll check it out and see if it works by adding UpdateSourceTrigger. Thanks for your help man.
Jorge Vargas