WPF MVVM DataGridColumn с условным StringFormat - PullRequest
0 голосов
/ 16 мая 2019

DataGridColumn 'Amount' моего приложения WPF MVVM имеет два шаблона в зависимости от 'Currency':

- сумма в долларах США: «1 000,12» (разрешить десятичную точку)
- сумма JPY: "5000" (Запретить десятичную точку)

Теперь он имеет только StringFormat USD. Для реализации двух шаблонов StringFormat я должен использовать <Style.Triggers>?

<DataGridTextColumn x:Name="PayAmt"
    Header="Amount" Binding="{Binding Amount, Mode=TwoWay,
    StringFormat={}{0:N2}, TargetNullValue='', UpdateSourceTrigger=LostFocus}" >
    <DataGridTextColumn.ElementStyle>
        <Style>
            <Setter Property="TextBlock.TextAlignment" Value="Right"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Amount}" Value="0"></DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGridTextColumn.ElementStyle>
</DataGridTextColumn>

<DataGridTextColumn x:Name="Currency" Header="Currency" Binding="{Binding Currency, Mode=TwoWay}">
    <DataGridTextColumn.ElementStyle>
        <Style>
            <Setter Property="TextBlock.TextAlignment" Value="Left" />
        </Style>
    </DataGridTextColumn.ElementStyle>
</DataGridTextColumn>


ViewModel: ( ОБНОВЛЕНО: После того, как я изменил вышеупомянутую привязку Amount на FormattedString, это сработало!)

private Nullable<decimal> _amount { get; set; }
public Nullable<decimal> Amount {
    get { return _amount; }
    set
    {
        if (Equals(_amount, value)) return;
        _amount = value;
        NotifyPropertyChanged("Amount");
        NotifyPropertyChanged("FormattedAmount");
    }
}

private string _currency;

public string Currency
{
    get => _currency;
    set
    {
        if (_currency == value) return;
        _currency = value;
        NotifyPropertyChanged("Currency");
        NotifyPropertyChanged("FormattedAmount");
    }
}

public string FormattedAmount
{
    get
    {
        switch (Currency)
        {
            case "JPY":
                return Amount?.ToString("N0");
            default:
                return Amount?.ToString("N2");
        }
    }
    set
    {
        if (decimal.TryParse(value, out var amount))
            Amount = amount;
        else
            NotifyPropertyChanged("FormattedAmount");
    }
}

1 Ответ

0 голосов
/ 16 мая 2019

Я бы предложил сделать это в модели представления.Вы можете создать новое свойство с именем FormattedAmount и привязать к нему.В геттере просто отформатируйте строку на основе валютыВот пример.

    private double _amount;

    public double Amount
    {
        get => _amount;
        set
        {
            if (_amount == value) return;
            _amount = value;
            OnPropertyChanged(nameof(Amount));
            OnPropertyChanged(nameof(FormattedAmount));
        }
    }

    private string _currency;

    public string Currency
    {
        get => _currency;
        set
        {
            if (_currency == value) return;
            _currency = value;
            OnPropertyChanged(nameof(Currency));
            OnPropertyChanged(nameof(FormattedAmount));
        }
    }

    public string FormattedAmount
    {
        get
        {
            switch (Currency)
            {
                case "JPY":
                    return Amount.ToString("N0");
                default:
                    return Amount.ToString("N2");
            }
        }
        set
        {
            if (double.TryParse(value, out var amount))
                Amount = amount;
            else
                OnPropertyChanged(nameof(FormattedAmount));
        }
    }

Затем измените свой xaml для привязки к новому свойству

<DataGridTextColumn x:Name="PayAmt"
Header="Amount" Binding="{Binding FormattedAmount}" >
  <DataGridTextColumn.ElementStyle>
      <Style>
          <Setter Property="TextBlock.TextAlignment" Value="Right"/>
      </Style>
  </DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
...