簡體   English   中英

如何在 Silverlight XAML 中引用另一個名稱空間中的綁定轉換器?

[英]How can I refer to a binding converter in another namespace in Silverlight XAML?

由於您顯然無法在 C# 中創建 Silverlight DataTemplate,因此我正在嘗試在 XAML 中創建一個。我有一個需要參考的轉換器,我在另一個命名空間中的 C# 中定義了它。 我試過這樣做:

<UserControl.Resources>
        <DataTemplate x:Key="PriceTemplate">
            <TextBlock Text="{Binding Price, Converter={Converters:PriceConverter}}" />
        </DataTemplate>
    </UserControl.Resources>

其中 Converters 是指向正確命名空間的 xmlns。 但是,我收到一個編譯錯誤:

類型“Converters:PriceConverter”像標記擴展一樣使用,但不是從 MarkupExtension 派生的。

我嘗試將 System.Windows.Markup.MarkupExtension 作為父級添加到我的轉換器中,但它顯然不存在於 Silverlight 中。

我如何在 XAML 中引用我的轉換器,而不必在 XAML 中重寫它?

您要先制作靜態資源,然后綁定到作為靜態資源的轉換器。

 <UserControl.Resources> 
   <conv:IntConverter x:Key="IntConverter"></conv:IntConverter> 
 </UserControl.Resources> 
 <StackPanel> 
    <TextBlock x:Name="Result" Margin="15" FontSize="20" 
              HorizontalAlignment="Center" VerticalAlignment="Center" 
               Text="{Binding Converter={StaticResource IntConverter}}"> 
    </TextBlock> 
 </StackPanel> 
</Window>

所以 "conv:" xml 命名空間注冊在文檔的頂部,就像使用自定義控件一樣:

xmlns:conv="clr-namespace:MyFooCompany.Converters"

此示例改編自以下有關 WPF 相同問題的鏈接教程:

http://www.dev102.com/2008/07/17/wpf-binding-converter-best-practices/

您似乎將類型與實例混淆了。 轉換器類型將存在於命名空間中,但是在綁定中我們沒有指定類型作為轉換器。 相反,我們為綁定提供了該類型的實際實例。

通常IValueConverter實例是無狀態的,因此我們可以在加載 DataTemplate 實例的可用資源字典鏈中的任何位置保存一個公共實例。

在 xaml 中,我們可以通過創建一個新別名來引用另一個命名空間來覆蓋它。 考慮到這一點,您的 xaml 可能如下所示:-

<UserControl x:Class="SilverlightApplication1.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SilverlightApplication1"
    xmlns:localConverters="clr-namespace:SilverlightApplication1.Converters">
    <UserControl.Resources>
        <localConverters:PriceConverter x:Key="PriceConverter" />
        <DataTemplate x:Key="Test">
            <TextBlock Text="{Binding Price, Converter={StaticResource PriceConverter}}" />
        </DataTemplate>
    </UserControl.Resources>
<RadioButton GroupName="Group1">
    <RadioButton.Template>
        <ControlTemplate>
            <ToggleButton IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}">
                <ToggleButton.Content>
                    <SymbolIcon Symbol="Edit"/>
                </ToggleButton.Content>
                <ToolTipService.ToolTip>
                    <ToolTip Content="Sample Tooltip" Placement="Mouse" />
                </ToolTipService.ToolTip>
            </ToggleButton>
        </ControlTemplate>
    </RadioButton.Template>
</RadioButton>

添加到@Rokk 發布的答案中。

除了建議在資源字典中創建 ValueConverter 實例的其他答案之外,另一種解決方案是通過 MarkupExtention 實現它:

public class IntToLetterConverter : IMarkupExtension<IValueConverter>, IValueConverter
{
    public IValueConverter ProvideValue(IServiceProvider serviceProvider)
        => (IValueConverter)this;

    object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
        => ((IMarkupExtension<IValueConverter>)this).ProvideValue(serviceProvider);

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        => (char)('a' + (int)value);

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        => (int)((char)value - 'a');
}

使用此解決方案,您可以直接引用轉換器(本質上是一個 MarkupExtension)而無需定義資源。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM