在Application.Resources中循环引用的IValueConverter [英] Circular referenced IValueConverter in Application.Resources

查看:37
本文介绍了在Application.Resources中循环引用的IValueConverter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了错误:

StaticResource not found for key maxLength

设置如下:

app.xaml中的转换器设置,其中还包含一个数据模板

Converter setup in app.xaml, which also contains a 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>
     ....

数据模板中HotelView.xaml中的

视图使用转换器

view in the HotelView.xaml which is in the datatemplate, uses the converter

....
      <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资源字典,它将起作用

If I move the converter to HotelView.xaml resource dictionary it works

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

If I change the reference to a DynamicResource it is not used

很明显,它具有最大长度的基本要求(它会缩短字符串并在所需的长度范围内添加'...'),我希望能够在整个应用程序中使用它,而不必在其中引用它多个资源词典.

Obviously with something as basic as max length (which shortens the string and adds '...' if its over the required length) I want to be able to use it through out the application, and not have to reference it in multiple resource dictionaries.

这是一个错误吗?

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

----------------- edit ------------------

好吧,我用一个包含以下内容的最小应用程序重现了此错误消息:

OK I have reproduced this errror with a minimum app consisting of:

App1.xaml

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

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

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仿真器在运行时引发错误

The error is thrown at runtime using the VS emulator

推荐答案

根据您的描述,您希望能够一次定义一个IValueConverter,并在任何Xamarin.Forms ContentPage中使用它,而无需使用以便继续在本地XAML页中指定转换器.

From what you mention you want to be able to define a IValueConverter the once, and use it from any Xamarin.Forms ContentPage, without the need to keep specifying the converter in the local XAML page.

这可以通过执行以下操作来实现:-

This can be achieved by doing the following:-

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

您将需要删除它,并添加一个名为App.cs的新Forms Xaml Page.

You will need to delete this, and add a new Forms Xaml Page called App.cs.

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

This will generate both the App.xaml and related App.cs files.

在此问题中,(如何对图像进行数据绑定?),有一个名为MyByteToImageSourceConverter的转换器.

In this question, (How can I databind an image?), there is a converter called 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>

因此,在上面我们用键定义了转换器,然后我们就可以从 all 其他Xamarin.Forms ContentPage引用.

So in the above we have defined our converter with a key, that we will then be able to reference from all other Xamarin.Forms ContentPage's.

App.cs

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

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

In the code-behind we need to change the default inheritance from ContentPage and specify 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中,我们可以在上面看到通过StaticResource kyByteToImageSourceConverter引用在App.xaml中指定的转换器.

In our ContentPage we can see above we are referencing the converter that we specified in App.xaml via the StaticResource kyByteToImageSourceConverter.

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

As that was definied in App.xaml, we can re-use this in all our pages without the need to specify the location of the converter locally.

为完整起见,其背后的代码是:-

For completeness the code-behind is:-

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中添加以下内容:-

You can have the following in your App.xaml:-

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

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

with local2:MyCustomView1 referencing your custom view, which for this example is defined as:-

<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>

此自定义视图仍使用App.xaml中指定的Converter,并且仍然呈现而无需ContentView类中本地指定Converter的需要.

This custom view still uses a Converter as specified from the App.xaml and does still render, without the need to specify the Converter locally within the ContentView class.

这篇关于在Application.Resources中循环引用的IValueConverter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆