WPF TextBlock StringFormat Binding To Parent

Go To StackoverFlow.com

1

I have been trying to bind the StringFormat of the Text property of a TextBlock to a templated parent.

Here is where I'm trying to set the StringFormat:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:DataFlowControls">

    <Style TargetType="{x:Type local:DfcEditTextBox}">
        <Setter Property="Margin" Value="-6, 0, -6, 0" />
        <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:DfcEditTextBox}">
                    <TextBlock x:Name="PART_TextBlock"
                               Padding="2, 0, 0, 0"
                               Text="{Binding Path=Value, StringFormat=ThisStringFormat, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}">
                    </TextBlock>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</ResourceDictionary>

Here is the parent:

<Window x:Class="DataFlowControls.Show.DfcListView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:dfc="clr-namespace:DataFlowControls;assembly=DataFlowControls"
        xmlns:local="clr-namespace:DataFlowControls.Show"
        Title="DfcListView" Height="400" Width="500">
    <Grid>
        <StackPanel>
            <dfc:DfcListView Name="lvTradesCollection" ItemsSource="{Binding Path=TradesCollection}" KeyboardNavigation.DirectionalNavigation="Continue" >
                <ListView.ItemContainerStyle>
                    <Style TargetType="ListViewItem">
                        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                    </Style>
                </ListView.ItemContainerStyle>
                <ListView.Resources>
                    <DataTemplate x:Key="Date_DataTemplate">
                        <dfc:DfcEditTextBox Value="{Binding Path=Date, Mode=Twoway, UpdateSourceTrigger=PropertyChanged}" ThisStringFormat='{}{0:dd/MM/yyyy}' HorizontalContentAlignment="Left" IsEditable="true" />
                    </DataTemplate>
                    <DataTemplate x:Key="Asset_DataTemplate">
                        <dfc:DfcEditTextBox Value="{Binding Path=Asset, Mode=Twoway, UpdateSourceTrigger=PropertyChanged}" HorizontalContentAlignment="Left" IsEditable="true" />
                    </DataTemplate>
                    <DataTemplate x:Key="Lots_DataTemplate">
                        <dfc:DfcEditTextBox Value="{Binding Path=Lots, Mode=Twoway, UpdateSourceTrigger=PropertyChanged}" ThisStringFormat='N2' HorizontalContentAlignment="Center" IsEditable="true" />
                    </DataTemplate>
                    <DataTemplate x:Key="Price_DataTemplate">
                        <dfc:DfcEditTextBox Value="{Binding Path=Price, Mode=Twoway, UpdateSourceTrigger=PropertyChanged}" HorizontalContentAlignment="Center" IsEditable="true" />
                    </DataTemplate>
                    <DataTemplate x:Key="IsCheap_DataTemplate">
                        <dfc:DfcEditCheckBox Value="{Binding Path=IsCheap, Mode=Twoway, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" IsEditable="true" />
                    </DataTemplate>
                    <DataTemplate x:Key="NextTrade_DataTemplate">
                        <dfc:DfcEditComboBox Value="{Binding Path=NextTrade, Mode=Twoway, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{x:Static local:DfcListView.NextTradeTypes}" IsEditable="true" />
                    </DataTemplate>
                </ListView.Resources>
                <ListView.View>
                    <dfc:DfcGridView>
                        <dfc:DfcGridViewColumn Header="Date" Width="140" CellTemplate="{StaticResource Date_DataTemplate}" />
                        <dfc:DfcGridViewColumn Header="Asset" Width="40" CellTemplate="{StaticResource Asset_DataTemplate}" />
                        <dfc:DfcGridViewColumn Header="Lots" Width="40" CellTemplate="{StaticResource Lots_DataTemplate}" />
                        <dfc:DfcGridViewColumn Header="Price" Width="50" CellTemplate="{StaticResource Price_DataTemplate}" />
                        <dfc:DfcGridViewColumn Header="IsCheap" Width="60" CellTemplate="{StaticResource IsCheap_DataTemplate}" />
                        <dfc:DfcGridViewColumn Header="NextTrade" Width="80" CellTemplate="{StaticResource NextTrade_DataTemplate}" />                                                                         
                    </dfc:DfcGridView>
                </ListView.View>
            </dfc:DfcListView>
            <Button Content="Add Row" HorizontalAlignment="Left" Margin="5,5,5,5" Click="AddRow_Click"/>
            <Button Content="Update Row" HorizontalAlignment="Left" Margin="5,5,5,5" Click="UpdateRow_Click"/>
        </StackPanel>
    </Grid>
</Window>

Everything works fine until I include the StringFormat=ThisStringFormat, which mucks it up. But I somehow need to connect the StringFormat to the ThisStringFormat property expressed in the parent. I've experimented with changing StringFormat=ThisStringFormat to try to get to the templated parent, but to no avail.

Any ideas on how to solve this one?

2012-04-04 06:26
by Damian


1

The StringFormat property is just a regular property on BindingBase and regular properties cannot be binding targets only dependency properties can. So the answer is: You cannot not do it that way.

Some possible approaches:

  1. Subclass TextBox and add a string format dependency property to which you can bind providing the required functionality
  2. Augment your view model (if you have one) with a FormattedValue property (probably a bit ugly)
  3. Use a MultiBinding for the Text property. One binding goes to Value and one to the ThisStringFormat of the templated parent. Then write a converter implementing IMultiValueConverter to return the formatted value.
2012-04-04 07:17
by ChrisWue
The third is to use MultiBinding with IValueConverter - Marat Khasanov 2012-04-04 07:28
Thanks... so simple, yet so right. I should have thought of this hours ago - Damian 2012-04-04 08:36
This doesn't quite work yet.. - Damian 2012-04-04 08:58
@MaratKhasanov Thanks I added it - ChrisWue 2012-04-04 09:17
Ads