初めてのポスターですが、何年もの間SOを読んでいて、ついに私が答えられなかった質問に出くわしました。
複数の列を持つ GridView をホストする ListView があります。1 つは価格を表示し、もう 1 つは通貨コード (CAD、USD、GBP など) を表示します。これはすべてEntity Frameworkを使用してSQLサーバーから引き出されるため、GridViewはクエリの結果を格納するIEnumerableにデータバインドされます。通貨コードは、適切な通貨を表示するために通貨をローカライズするために (このアプリの WinForms バージョンで) String.Format() で以前に使用されたローカライズ文字列 (en-US、en-GB) を含む別のテーブルに格納されます。形式と記号。
私が抱えている問題は、Price バインディングの ConverterCulture を Currency.LocalizedCultureName にバインドして正しくフォーマットする XAML にあります。これが私の現在のXAMLです:
<ListView Grid.Column="0" Name="pricingListingListView" ItemsSource="{Binding Source={StaticResource pricesByYear}}">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<GroupBox Header="{Binding Name}" Margin="0,0,0,10">
<ItemsPresenter/>
</GroupBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
<ListView.View>
<GridView>
<GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Date" DisplayMemberBinding="{Binding Source.Date}" Width="60" />
<GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Price" DisplayMemberBinding="{Binding Price, StringFormat='{}{0:C}', ConverterCulture={Binding Currency.LocalizedCultureName}}" Width="60" />
<GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Currency" DisplayMemberBinding="{Binding Currency.Code}" Width="60" />
<GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Unit" DisplayMemberBinding="{Binding Unit.Name}" Width="60" />
<GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Source" DisplayMemberBinding="{Binding Source.Name}" Width="125" />
<GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Project" DisplayMemberBinding="{Binding Project.Description}" Width="125" />
<GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Plant Type" DisplayMemberBinding="{Binding Project.Plant.Name}" Width="100" />
</GridView>
</ListView.View>
</ListView>
PriceByYear は、私のコード ビハインドで DP から IEnumerable を引き出す単なる CollectionViewSource です。フォーマットされていないだけで、データは正しく引き出されます。
これは正常にコンパイルされますが、それを含むウィンドウを読み込むと XamlParseException が生成されます。「Binding」タイプの「ConverterCulture」プロパティに「Binding」を設定することはできません。「Binding」は、DependencyObject の DependencyProperty でのみ設定できます。
エラーを生成する行は次のとおりです。 " 幅="60" />
短い形式の目的は、価格を表示することですが、文字列値として格納されているカルチャ名に従って書式設定します。グリッドビューの各行は異なる可能性があります。バインディング内でバインドできないようですが、これについて別の方法はありますか?
答え
マルチバインディングはトリックを行いました。これが実際の XAML です。
<local:LocalizeCurrencyMultiConverter x:Key="localizeCurrencyMultiConverter"/>
...
<GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Price" Width="60">
<!--DisplayMemberBinding="{Binding Price, StringFormat='{}{0:C}', ConverterCulture={Binding Currency.LocalizedCultureName}}"-->
<GridViewColumn.DisplayMemberBinding>
<MultiBinding Converter="{StaticResource localizeCurrencyMultiConverter}">
<Binding Path="Price"/>
<Binding Path="Currency.LocalizedCultureName"/>
</MultiBinding>
</GridViewColumn.DisplayMemberBinding>
</GridViewColumn>
そしてコンバータークラス:
public class LocalizeCurrencyMultiConverter :System.Windows.Data.IMultiValueConverter {
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
string localizedCurrency;
if (!values.Any() || values[0] == null)
throw new ArgumentException("Convert requires a minimum a price to display, and optionally a culture.");
double originalCurrency;
if (!double.TryParse(values[0].ToString(), out originalCurrency))
return values[0];
string localization = (values[1] ?? "en-CA").ToString();
try {
localizedCurrency = string.Format(System.Globalization.CultureInfo.CreateSpecificCulture(localization), "{0:c}", originalCurrency);
} catch {
localizedCurrency = string.Format(System.Globalization.CultureInfo.CreateSpecificCulture("en-CA"), "{0:c}", originalCurrency);
}
return localizedCurrency;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) {
throw new NotImplementedException();
return null;
}
}
魅力のように機能します。