循环引用Application.Resources中的IValueConverter

时间:2016-02-26 14:50:14

标签: xaml xamarin xamarin.forms

我收到错误:

StaticResource not found for key maxLength

设置如下:

app.xaml中的转换器设置,其中还包含一个datatemplate

          <Application.Resources>
            <ResourceDictionary>
              <ext:MaxLengthStringConverter x:Key="maxLength"/>
    ....
          <DataTemplate x:Key="HotelViewModel">
            <tripSegmentPartViews:HotelView
                    Padding="0"
                    HeightRequest="60"
                    BorderWidth="1"
                    BorderColor="{ext:ColourResource Divider}"
                    BordersToDraw="{x:Static controls:Borders.Top}"
                    BackgroundColor="Transparent"/>
          </DataTemplate>
     ....

在datatemplate中的HotelView.xaml中查看,使用转换器

....
      <Label Text="{Binding HotelName, Converter={StaticResource maxLength}, ConverterParameter=10}"
              AbsoluteLayout.LayoutFlags="All"
              AbsoluteLayout.LayoutBounds="1,0.2,0.62,0.5"
              VerticalOptions="End"
              HorizontalOptions="Start"
              FontSize="20"
              />
....

如果我将转换器移动到HotelView.xaml资源字典,它可以工作

如果我更改了对DynamicResource的引用,则不使用

显然有一些基本的东西,如最大长度(缩短字符串并添加&#39; ...&#39;如果它超过所需长度)我希望能够在整个应用程序中使用它,并且不必在多个资源字典中引用它。

这是一个错误吗?

-----------------编辑------------------

好的我用最少的应用程序复制了这个错误:

App1.xaml

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="App1.App"
             xmlns:ext="clr-namespace:App1.Extensions;assembly=App1"
             xmlns:local="clr-namespace:App1;assembly=App1">
  <Application.Resources>
    <ResourceDictionary>
      <ext:MyConverter x:Key="conv"></ext:MyConverter>
      <DataTemplate x:Key="dt">
        <local:View1></local:View1>
      </DataTemplate>
    </ResourceDictionary>
  </Application.Resources>
</Application>

的Page1.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="App1.Page1"
             xmlns:local="clr-namespace:App1;assembly=App1">
  <StackLayout>
  <Label Text="Page1" VerticalOptions="Center" HorizontalOptions="Center" TextColor="White" />
    <ListView ItemTemplate="{StaticResource dt}" ItemsSource="List">

    </ListView>
  </StackLayout>
</ContentPage>

View1.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="App1.View1"
             xmlns:ext="App1.Extensions">
  <Label Text="{Binding MainText, Converter={StaticResource conv}" VerticalOptions="Center" HorizontalOptions="Center" TextColor="White"/>
</ContentView>

App1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Xamarin.Forms;

namespace App1
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            // The root page of your application
            Page1 p = new Page1();
            p.BindingContext = new {
                MainText = "test",
                List = new List<string>() { "test"}
            };
            var navContainer = new NavigationPage(p);
            navContainer.BarBackgroundColor = Color.Red;
            navContainer.BarTextColor = Color.White;

            MainPage = navContainer;
        }
    }
}

使用VS模拟器

在运行时抛出错误

1 个答案:

答案 0 :(得分:0)

根据您的提及,您希望能够定义一次IValueConverter,并在任何Xamarin.Forms ContentPage中使用它,而无需在本地指定转换器XAML页面。

这可以通过以下方式实现: -

在您的PCL中,您通常拥有App.cs

您需要将其删除,然后添加名为Forms Xaml Page的新App.cs

这将生成App.xaml和相关的App.cs文件。

在这个问题中,(How can I databind an image?),有一个名为MyByteToImageSourceConverter的转换器。

我将使用此说明: -

<强>的App.xaml

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="SampleApp.App"

         xmlns:local="clr-namespace:{namespace reference goes here to the converter}"
         >

    <Application.Resources>
        <ResourceDictionary>

            <local:MyByteToImageSourceConverter x:Key="kyByteToImageSourceConverter"/>

        </ResourceDictionary>
    </Application.Resources>

</Application>

因此,在上面我们已经使用密钥定义了转换器,然后我们将能够从所有其他Xamarin.Forms ContentPage中引用。

<强> App.cs

namespace SampleApp
{
    public partial class App
        : Xamarin.Forms.Application
    {
        public App()
        {
            InitializeComponent();
            //
            this.MainPage = new ByteToImageExample2();
        }
    }
}

code-behind中,我们需要更改ContentPage的默认继承并指定Xamarin.Forms.Application

我们还通过this.MainPage = ...

指定了我们的启动页面

<强> ByteToImageExample2.xaml : -

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="SampleApp.ByteToImageExample2"
         >

    <StackLayout>

        <Image Source="{Binding MyImageAsBytes, Converter={StaticResource kyByteToImageSourceConverter}}"/>

    </StackLayout>

</ContentPage>

在我们的ContentPage中,我们可以看到我们通过App.xaml引用了我们在StaticResource kyByteToImageSourceConverter中指定的转换器。

正如App.xaml中定义的那样,我们可以在所有页面中重复使用它,而无需在本地指定转换器的位置。

为了完整性,代码隐藏是: -

<强> ByteToImageExample2.cs : -

public partial class ByteToImageExample2 : ContentPage
{
    public ByteToImageExample2()
    {
        InitializeComponent();
        //
        byte[] bytImage = { your image as a byte collection }
        //
        this.BindingContext = new MyImageViewModel()
        {
            MyImageAsBytes = bytImage
        };
    }
}

更新1: -

您可以在App.xaml中添加以下内容: -

  <DataTemplate x:Key="kyByteToImage3ExampleDataTemplate2">
    <ViewCell>
      <local2:MyCustomView1/>
    </ViewCell>
  </DataTemplate>

local2:MyCustomView1引用您的自定义视图,此示例定义为: -

<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="SampleApp.MyCustomView1">

    <Image Source="{Binding MyImage, Converter={StaticResource kyByteToImageSourceConverter}}" Aspect="AspectFit" />

</ContentView>

此自定义视图仍然使用Converter中指定的App.xaml,并且仍会呈现,没有需要在{{}内本地指定Converter {1}}上课。