Windowsフォームアプリケーションに追加されているWPFコントロールライブラリがあります。コントロールをローカライズできるようにしたいのですが、コードを複製せずにこれを完全に実現する方法がわかりません。 これは私が今していることです 。
基本的に、Windowsフォームアプリでは、メインアプリケーションが起動する前に、フォームアプリ内にあるApp.xamlをインスタンス化しています(フォームアプリ内にもあるリソースへのリンクが含まれています)。これは実行時に完全に機能します。
ただし、私のユーザーコントロールにはすべて_Content="{StaticResource SomeVariableName}"
_があり、空白になってしまいます。これを修正するには、app.xamlと、Windowsフォームアプリのものと一致する適切なリソース辞書をコントロールライブラリに配置します。ただし、これは重複したコードです。
私がすでに役に立たなかったこと:
Uri resourceLocater = new Uri("/WindowsFormsApplication3;component/app.xaml", UriKind.Relative);
を指しますそれで、これを機能させ、コンポーネントのデフォルトを設計時に表示し、重複を回避する方法はありますか?または、この場合の複製は問題ありませんか? 2番目の箇条書きのサブアイテムに問題がないように見える場合(ビルドコピーされたリソース辞書を使用してApp.xamlを複製)、コンポーネントレベルのアイテムではなく、ファイルレベルのアイテムを検索するようにするにはどうすればよいですか?
私が注意を払った最後の質問(そして必要に応じてこれを個別に投稿できます)。私のApp.xamlはコードに組み込まれているため、とにかくその場で新しいResourceDictionariesを作成することはできません。これを行う方法はありますか?
最後のオプション...おそらく最良のオプション?とにかくAndre van Heerwaardeのコードを使用する予定です ファイルの存在を確認し、その場でマージされたリソースとして追加しますか?基本的に、デフォルトの埋め込みResourceDictionaryにリンクする1つのApp.xamlをユーザーコントロールに配置します。そして、コードにその場で適切なローカライズされたリソースを探しさせますか?それは相対的なファイルパスである可能性がありますか?ここで私が見る唯一の欠点は、デフォルトをその場で変更できないことです...おそらく、指定された場所で(ある種の規則を使用して)その外観を持ち、組み込みのものよりも優先される可能性がありますか?
ああ、埋め込みリソースが必要ない理由は、ビルドのデプロイ後にエンドユーザーが新しいローカライズされたリソースを追加/変更できるようにするためです。
これをよりよく視覚化するのに役立つ場合は、コードを追加できます。お知らせください。
[〜#〜]更新[〜#〜]
私は今、ローカライズだけでなく、スタイリングに関するさらなる問題に直面しています。
コントロールの1つにある内部ボタンの1つの例を次に示します。
_<Button Style="{StaticResource GrayButton}"
_
私が試した/考えた他のいくつかのこと:
これが接続ケースです これは実際に私が探しているもののように聞こえますが、これに対する実際の解決策は提供されていません
私が考えることができる(そしてまだ試していない)解決策(トップを超えて..それは機能しません)も、私が単純であるべきだと思う何かのための多くの作業のようです。ただし、バインドできるいくつかの依存関係プロパティをコントロールに作成し、それらをコントロールを使用するプロジェクトでオーバーライドできるようにすることができる場合があります。私が言ったように、それは非常に単純な要求のために多くの仕事のように思えます:)。これでもうまくいくでしょうか?そしてもっと重要なことに、私が見逃しているより良い、より単純な解決策はありますか?
私は一度この問題に遭遇しましたが、「リソースは正規辞書のキーによってインデックス付けされたオブジェクトです」というもの全体を削除することで解決しました。
つまり、あるプロジェクトでリソースを定義し、その「キー」によって別のプロジェクトでリソースを参照するという単純な事実は、正気の人に鳥肌を与えるはずです。 強い参照が欲しかった。
この問題に対する私の解決策は、リソースxamlファイルを各リソースのプロパティを持つ静的クラスに変換する カスタムツール を作成することでした。
したがって、MyResources.xaml:
<ResourceDictionary>
<SolidColorBrush x:Key="LightBrush" ... />
<SolidColorBrush x:Key="DarkBrush" ... />
</ResourceDictionary>
MyResources.xaml.csになります
public static class MyResources {
static MyResources() {
// load the xaml file and assign values to static properties
}
public static SolidColorBrush LightBrush { get; set; }
public static SolidColorBrush DarkBrush { get; set; }
}
リソースを参照するには、StaticResource
の代わりにx:Static
を使用できます。
<Border
Fill="{x:Static MyResources.LightBrush}"
BorderBrush="{x:Static MyResources.DarkBrush}"
... />
これで、リソースの強力な参照、オートコンプリート、コンパイル時のチェックが可能になりました。
私もスタイリングテーマと利用可能な静的リソースの処理に問題がありました。そこで、以前のリンクされた質問のMERGEDリソースのように、基本的に使用するテーマだけがネストされたスタンドアロンライブラリを作成しました。
次に、Windowsフォーム(.xaml)で、そのライブラリへの参照を配置します。
<Window x:Class="MyAppNamespace.MyView"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation" ... />
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- Common base theme -->
<ResourceDictionary Source="pack://application:,,,/MyLibrary;component/Themes/MyMainThemeWrapper.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Rest of XAML for the WPF window>
</Window>
「コンポーネント」は、指定された「MyLibrary」プロジェクトのルートを参照しているように見えます。実際のプロジェクトでは、「Themes」というサブフォルダーを作成したため、ソースには...; component/Themes/..が含まれています。
「MyMainThemeWrapper.xaml」は、ネストされたマージリソースディクショナリに非常によく似ており、他のライブラリからすべてを完全に認識します。
これがあなたの問題に対する私のpartial解決策です。緩いリソースを処理しようとはしていませんが、WinFormsとWPFの間でリソースを共有することである程度の成功を収めています。
Infralution.Localization.Wpf マークアップ拡張機能とカルチャマネージャーを使用して、WPFからリソースライブラリ内のリソースを参照します。
<TextBlock Text="{Resx ResxName=ResourceLib.Resources, Key=Test}"/>
WPFユーザーコントロールのコンテンツを、コントロールテンプレートとして1つ以上のリソースディクショナリに配置します。
<ControlTemplate x:Key="TestTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="{Resx ResxName=ResourceLib.Resources, Key=Test}"/>
</Grid>
</ControlTemplate>
ユーザーコントロールでリソーステンプレートを使用する
<UserControl x:Class="WpfControls.UserControl1"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.Microsoft.com/expression/blend/2008" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" >
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ResourceDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<ContentControl Template="{StaticResource TestTemplate}" />
</UserControl>
物事を機能させるために数行のコードを追加します
public partial class UserControl1 : UserControl
{
// we require a reference to the resource library to ensure it's loaded into memory
private Class1 _class1 = new Class1();
public UserControl1()
{
// Use the CultureManager to switch to the current culture
CultureManager.UICulture = Thread.CurrentThread.CurrentCulture;
InitializeComponent();
}
}
これが単純な デモアプリ WindowsFormsHost.7zと呼ばれるものです