Question

I have a DataGridTemplateColumn than contains a UserControl:

 <DataGridTemplateColumn Header="Projection"
                                SortMemberPath="SelectedItem"
                                ClipboardContentBinding="{Binding ProjectionMethod.Value, Mode=TwoWay}"
                                >
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <local:DataGridComboBoxCellControl DataContext="{Binding}"
                                                       SelectedItem="{Binding ProjectionMethod.Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                                       ItemsSource="{Binding ProjectionMethodsTextWrapper, Mode=OneWay}"
                                                       ErrorMessage="{Binding ProjectionMethod.ErrorMessage, Mode=OneWay}">

                    </local:DataGridComboBoxCellControl>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

The UserControl bindings are done with DependencyProperties I set up inside the UserControl definition.

For the most part, the control works fine. But when pasting, even though the contents visually appear to be pasted, the cell never commits the paste contents to ProjectionMethod.Value (even though it is set as the ClipboardContentBinding). Debugging reveals that the setter of ProjectionMethod.Value is never even called.

Even more strangely, the constructor of the UserControl is being called during paste. I have no idea why this is occurring. I am pasting to existing cells, no new rows are being created. I was assuming the ClipboardContentBinding routes straight to the underlying property ProjectionMethod.Value. Why the paste command is even bothering with UI controls is a mystery to me.

It seems this problem might require someone with a fairly deep understanding of WPF.

(Here is the current xaml of the UserControl. Right now it's basically a TextBlock and a ComboBox with a few other controls for displaying errors. Any lines with ElementName=parentControl are bindings to dependency properties. Both the TextBlock and ComboBox bind to the same SelectedItem DP.

<UserControl x:Class="DataGridComboBoxCellControl"
         x:Name="parentControl"
         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" 
         xmlns:local="clr-namespace:MyProject"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">

<UserControl.Resources>
    <local:MyStringToThicknessConverter x:Key="PopToOne" PopString="1" EmptyString="0"/>
    <local:MyStringToVisibilityConverter x:Key="PopToVis" PopString="Visible" EmptyString="Collapsed"/>
</UserControl.Resources>

<Grid ToolTip="{Binding ElementName=parentControl, Path=ErrorMessage, Mode=OneWay}"
      IsEnabled="{Binding IsProjectionEnabled}" >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <Border Grid.ColumnSpan="3" BorderThickness="{Binding ElementName=parentControl, Path=ErrorMessage, Mode=OneWay, Converter={StaticResource PopToOne}}" 
            BorderBrush="Red"/>
    <Control Grid.Column="0"
             Margin="1,0"
             Template="{DynamicResource local:MyStyleRef, ResourceKey=errorGrid}"
             Visibility="{Binding ElementName=parentControl, Path=ErrorMessage, Mode=OneWay, Converter={StaticResource PopToVis}}"/>
    <TextBlock Grid.Column="1" Text="{Binding ElementName=parentControl, Path=SelectedItem, Mode=OneWay}" VerticalAlignment="Center"/>
    <ComboBox Grid.Column="2"
            Style="{DynamicResource local:MyStyleRef, ResourceKey=noText_ComboBoxStyle}"
            ItemsSource="{Binding ElementName=parentControl, Path=ItemsSource, Mode=OneWay}"
            SelectedItem="{Binding ElementName=parentControl, Path=SelectedItem}"  />
    </Grid>
</UserControl>

Update I have now tried getting rid of the UserControl altogether and dumping its xaml code directly into the DataTemplate of the TemplateColumn - the same issue more or less. Visually the paste appears to execute, but the setter of ProjectionMethod.Value is never called and the viewmodel is therefore never updated. I am using the OnPastingCellClipboardContent command to paste.

Was it helpful?

Solution

I think I figured it out. I set the update trigger for the clipboard paste to PropertyChanged:

ClipboardContentBinding="{Binding ProjectionMethod.Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

And now the value is being committed immediately when pasting. I don't know what the default behavior is supposed to be, but before the paste values were never committed, even after row leave. And still not sure why the UserControl's constructor was being called.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top