Как динамически изменять формат строки валюты в сетке данных WPF

#c# #.net #wpf #datagrid #culture

Вопрос:

У меня есть приложение WPF с сеткой данных, которая содержит некоторые цены. Я хочу динамически изменять валюту, и формат столбца также должен быть скорректирован.

Единственный способ, который я нашел, — это установить формат таким образом:

 <DataGridTextColumn Header="Price" Width="95" Binding="{Binding Path=Price, StringFormat=C, ConverterCulture='en-US'}" />
 

Но эта привязка статична. Когда я пытаюсь привязать ConverterCulture к значению из кода, возникает ошибка привязки.

 <DataGridTextColumn Header="Price" Width="95" Binding="{Binding Path=Price, StringFormat=C, ConverterCulture="{Binding Source=CurrencyCulture}" />
 

Есть ли какой-либо способ динамического изменения конвертеркультуры в формате столбца Datagrid?

Комментарии:

1. Привязки могут быть заданы только свойством DependecyProperty, объявленным в объекте DependecyObject. Но сама привязка-это расширение наценки. И свойства в нем (включая конвертеркультуру) являются обычными свойствами CLR. Если вам нужно реализовать это в привязке в одном или двух свойствах, то самый простой способ-использовать многосвязку и а мультиконвертер.

Ответ №1:

Есть ли какой-либо способ динамического изменения конвертеркультуры в формате столбца Datagrid?

Установите Language свойство DataGrid :

 <DataGrid Language="fr-FR" ...>
 

Это свойство зависимости, к которому вы можете привязаться.

Комментарии:

1. Я хочу изменить формат только для одного столбца, а не для всей сетки данных.

Ответ №2:

Я не тестировал его, поэтому не могу сказать, работает ли он наверняка, но вы можете попробовать что-то подобное со стилем и дататриггером. В этом примере вам понадобится зависимое свойство «валюта», для которого вы установили значение «USD», чтобы инициировать изменение, однако вы можете настроить триггер в соответствии с вашими потребностями:

 <DataGridTextColumn Header="Price" Width="95" Binding="{Binding Path=Price, StringFormat=C, ConverterCulture="{Binding Source=CurrencyCulture}">
    <DataGridTextColumn.CellStyle>
        <Style TargetType="DataGridCell">
            <Setter Property="Binding" Value="{Binding Path=Price, StringFormat=C, ConverterCulture="{Binding Source=CurrencyCulture}"
            <Style.Triggers>
                <DataTrigger Binding="Currency" Value="USD">
                    <Setter Property="Binding" Value="{Binding Path=Price, StringFormat=C, ConverterCulture='en-US'}"
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGridTextColumn.CellStyle>
<DataGridTextColumn/>
 

Надеюсь, это решит вашу проблему или направит вас в нужном направлении

Комментарии:

1. Как я понимаю, в этом случае я должен определить все возможные валюты в xaml. Но я хочу определить валюту во время выполнения не статически.

2. просто создайте переменную типа валюта или культура и свяжите ее с ней, а затем

Ответ №3:

Наконец я нашел решение. Не идеально, но, похоже, работает. CurrentContext-это мой статический класс для хранения переменных. Выбранная валюта.Код валюты-это 3-символьный код валюты, такой как доллар США или евро. Когда я меняю валюту в выпадающем списке, формат строки в столбце также меняется с нужным символом валюты.

CultureConverter.cs

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


            return String.Format(CurrentContext.CultureInfo, "{0:C}", values[0]);
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
 

Форма.xaml

 <Window.Resources>
        <providers:CultureConverter x:Key="CultureConverter" />
    </Window.Resources>

DataGrid Name="Datagrid" ItemsSource="{Binding Items, Mode=TwoWay}" AutoGenerateColumns="False">
  <DataGrid.Columns>
...
    <DataGridTemplateColumn>
      <DataGridTemplateColumn.CellTemplate>
         <DataTemplate>
           <TextBlock>
             <TextBlock.Text>
               <MultiBinding Converter="{StaticResource CultureConverter}">
                 <Binding Path="InitialCost" />
               </MultiBinding>
             </TextBlock.Text>
           </TextBlock>
         </DataTemplate>
       </DataGridTemplateColumn.CellTemplate>
   </DataGridTemplateColumn>
...
  </DataGrid.Columns>
</DataGrid>
 
 private void CB_Currency_SelectionChanged(object sender, SelectionChangedEventArgs e)
{

    CurrentContext.CultureInfo = 
    CultureInfo.GetCultures(CultureTypes.SpecificCultures)
                          .Where(x => new RegionInfo(x.LCID)
                          .ISOCurrencySymbol == SelectedCurrency.CurrencyCode)
                          .First();
}