1

I have a WPF DataGrid with numeric columns that are initially formatted without decimals.

The user has a checkbox to select the numeric format to show 0 or 2 decimal places. Below is shown the xaml for the column.

<DataGridTemplateColumn Header="Qty" Width="40" IsReadOnly="False" CellStyle="{StaticResource EditCell}">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding ItemQuantity, StringFormat={}{0:#}}" TextAlignment="Right" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <TextBox x:Name="textbox"  BorderThickness="0" HorizontalContentAlignment="Right" Background="LightYellow">
                <Binding Path="ItemQuantity" StringFormat="N0" UpdateSourceTrigger="LostFocus" >
                    <Binding.ValidationRules>
                        <c:DecimalRangeRule Min="0" Max="999999.99"/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox>
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

How can I change the column StringFormat setting when the checkbox is changed?

EDIT: Solution

I used a MultiConverter (as suggested by nit) to select the format based on whether the checkbox is checked:

//==========================================================================
public class NumericFormatConverter : IMultiValueConverter
{
    private const string FormatN0 = "{0:#,##0;-#,##0; }";
    private const string FormatN2 = "{0:#,##0.00;-#,##0.00; }";

    public object Convert( object[] values, Type targetType, object parameter, CultureInfo culture )
    {
        if ( values[0] == null ) return string.Empty;

        decimal num = 0;
        Decimal.TryParse( values[0].ToString(), out num );

        string format = FormatN0;
        bool isSmallValue = (values[1] == null ? false : (bool)values[1]);
        if ( isSmallValue ) format = FormatN2;

        return String.Format( format, num );
    }

    public object[] ConvertBack( object value, Type[] targetTypes, object parameter, CultureInfo culture )
    {
        decimal num = 0;
        Decimal.TryParse( value.ToString(), out num );

        object[] objects = new object[1] {num};
        return objects;
    }
}

The DataGridTemplateColumn changed to use MultiBinding:

<DataGridTemplateColumn Header="Qty" Width="40" IsReadOnly="False"  CellStyle="{StaticResource EditCell}">
    <DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <TextBlock HorizontalAlignment="Right" >
                <TextBlock.Text>
                <MultiBinding Converter="{StaticResource NumericFormat}">
                <Binding Path="GroupQuantity" />
                <Binding ElementName="chkSmallValue" Path="IsChecked"/>
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    </DataTemplate>

    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
    <DataTemplate>
        <TextBox x:Name="textbox" BorderThickness="0" HorizontalContentAlignment="Right" Background="LemonChiffon" PreviewTextInput="TextBox_PreviewTextInput" >
            <MultiBinding Converter="{StaticResource NumericFormat}"  UpdateSourceTrigger="LostFocus">
            <Binding Path="GroupQuantity" />
            <Binding ElementName="chkSmallValue" Path="IsChecked" Mode="OneWay"/>
            </MultiBinding>
        </TextBox>
    </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
4

3 に答える 3

3

StringFormat は依存プロパティではないため、任意の値にバインドして変更することはできません。これを変更するには、セルのビジュアル ツリーで TextBlock を見つけて、コード ビハインドで BindingExpression の StringFormat を変更する必要があります。しかし、この方法は臭いです。

できることは、StringFormat を使用せず、代わりに MultiValueConverter を使用して TextBlock.Text を Checkbox IsChecked プロパティと ItemQuantity にマルチバインドすることです。コンバーター内では、チェックボックスの IsChecked に応じてフォーマットされた文字列を返すことができます

于 2013-10-01T16:28:41.670 に答える
0

ViewModel に移動する EventToCommandTrigger を使用して、ItemQuantity の小数点以下の桁数を変更できます。

ViewModel でこれを行うと、テスト目的で機能に関する単体テストを作成できます。

于 2013-10-01T17:12:23.833 に答える