2017-07-20 1 views
0

私はPCL(共有プロジェクトではない)を利用するXamarin.Formsプロジェクトに取り組んでいます。
AndroidとiOSプロジェクトのResourcesフォルダにいくつかの画像があります。Xamarin:PCL(リソースからではない)からボタンに画像を追加

これは動作し、彼らはことになっていると、アイコンがボタンに表示:

<Button Image="speaker.png" Grid.Row="0" Grid.Column="0" /> 

私はまた、いくつかの画像と私のPCLプロジェクト内のフォルダを持っている:画像/アイコン/ speaker.png
私はこれ試してみた:...

<Button Image="{local:EmbeddedImage TestThree.images.icons.speaker.png}" /> 

を...しかし、それはうまくいきませんでした

PCLプロジェクトの画像フォルダの画像を表示するボタンがあります。
だから私の質問は...ここ

<Button WHAT GOES HERE? Grid.Row="0" Grid.Column="0" /> 

答えて

1

Button.ImageがFileImageStreamを必要とするとき、私は彼にそれを渡します。しかし、プロジェクトのイメージとして、PCL(または.NET標準2.0)ライブラリ(プロジェクト)に埋め込みリソースPNGファイルを使用しています。 たとえば、PCLプロジェクト名は "MyProject"で、画像はサブフォルダ "Images \ Icons \ ok.png"に配置されています。次に、リソース名(ImageSource.FromResourceなど)は「MyProject.Images.Icons.ok.png」です。 このメソッドは、埋め込みリソースファイルをアプリケーションのローカルストレージ内のファイルにコピーします(初回のみ)。

public static async Task<string> CopyIcon(string fileName) 
{ 
    if (String.IsNullOrEmpty(fileName)) return ""; 
    try 
    { 
     // Create (or open if already exists) subfolder "icons" in application local storage 
     var fld = await FileSystem.Current.LocalStorage.CreateFolderAsync("icons", CreationCollisionOption.OpenIfExists); 
     if (fld == null) return ""; // Failed to create folder 

     // Check if the file has not been copied earlier 
     if (await fld.CheckExistsAsync(fileName) == ExistenceCheckResult.FileExists) 
      return (await fld.GetFileAsync(fileName))?.Path; // Image copy already exists 

     // Source assembly and embedded resource path 
     string imageSrcPath = $"MyProject.Images.Icons.{fileName}"; // Full resource name 
     var assembly = typeof(FileUtils).GetTypeInfo().Assembly; 

     // Copy image from resources to the file in application local storage 
     var file = await fld.CreateFileAsync(fileName, CreationCollisionOption.OpenIfExists); 
     using (var target = await file.OpenAsync(PCLStorage.FileAccess.ReadAndWrite)) 
     using (Stream source = assembly.GetManifestResourceStream(imageSrcPath)) 
      await source.CopyToAsync(target); // Copy file stream 

     return file.Path; // Result is the path to the new file 
    } 
    catch 
    { 
     return ""; // No image displayed when error 
    } 
} 

私は通常のファイルを持っていますが、私はFileImageStream(Button.Image)に使用できます。 最初のオプションは、コードから使用します。

public partial class MainPage : ContentPage 
{ 
    protected async override void OnAppearing() 
    { 
     base.OnAppearing(); 
     btnOk.Image = await FileUtils.CopyIcon("ok.png"); 
    } 
} 

また、XAMLでも使用できますが、IMarkupExtensionインターフェイスの実装を作成する必要があります。

[ContentProperty("Source")] 
public class ImageFileEx : IMarkupExtension 
{ 
    public string Source { get; set; } 

    public object ProvideValue(IServiceProvider serviceProvider) 
    { 
     return Task.Run(async() => await FileUtils.CopyIcon(Source)).Result; 
    } 
} 

ここで、イメージをXAMLで直接割り当てることができます。 NuGet PCLStorageが必要とされている。この解決のために

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      xmlns:local="clr-namespace:MyProject" 
      x:Class="MyProject.MainPage" 
      xmlns:lcl="clr-namespace:MyProject;assembly=MyProject"> 
    <Grid VerticalOptions="Fill" HorizontalOptions="Fill"> 
     <Button Image="{lcl:ImageFileEx Source='ok.png'}" Text="OK" /> 
    </Grid> 
</ContentPage> 

0

なり、this議論とthisメッセージを見て、特に

0

性質が異なるタイプにバインドされているためである動作しません理由。

ボタンのImageプロパティには、 "FileImageSource" を取る - ローカルからGithub

からGithub

ImageのSourceプロパティには、 "ImageSourceは" を取ります。EmbeddedImageイムはXamarin forms image docs

から拡張子を使用していた推測しますこれは、 "FileImageSource"の代わりに "StreamImageSource"をロードするため、動作しません。

実際には、異なる寸法の画像(@ 2x、xhdpiなど)から読み込まれず、品質の悪い画像が表示され、複数の解像度をサポートしないため、これを行うべきではありません。

TapGestureRecognizerのビューコンテナ(スタックレイアウトなど)とその内部にイメージを置くことができます。または、本当に価値のあるカスタムレンダラーを作成できます。これらのどれもまだ明らかに複数の画像を扱うことはできません。

適切な解決策は、ベース(私は、MDPI AndroidまたはiOSの場合は1Xと仮定します)から正しいサイズの画像を生成し、正しいフォルダに入れ、作業ボタンの例で参照することです。

関連する問題