xamlの改善:バインド可能なコンバーター、スイッチコンバーター、セット

確かに、xamlコードはやや冗長であり、開発中に不快感を感じることがあります。 この記事では、マークアップのレイアウトを大幅に改善して読みやすくする最適化を検討します。 これは、データバインディングメカニズムに本質的に関連しているコンバーターでの作業に特に当てはまります。



過去の記事からの知識、特に直接注入の原理の理解が必要です。





バインド可能なコンバーター



遅かれ早かれ、多くのxaml開発者は疑問に直面します。パラメーターのバインディングをサポートするコンバーターを作成することは可能ですか? ただし、 IValueConverterインターフェイスの実装に加えて、 DependencyObjectクラスを継承し、コンバーターでDependencyPropertyを宣言しても、 コンバーターはビジュアルツリーの要素ではないため、ほとんどの場合、バインディングは機能しません! もちろん、さらに先へ進んで、パフォーマンスに気付かれないようにハイブリッドコントロールコンバーターを作成することもできますが、そのようなエキゾチックなソリューションは美しいとは言えず、その適用範囲は限られています。



しかし、 StoreBindingDependency Converterに適用することを妨げるものは何もないので、直接注入の原則が助けになります



<BooleanConverter x:Key="BindableConverter" OnTrue="Value1" OnFalse="Value2" OnNull="{StoreBinding StoreKey=viewModels: SettingsViewModel, Path=AnyValue3}"/>
      
      





独創的なものはすべてシンプルです!



この方法では、同じビュー上にある場合でも、ビジュアルツリーの要素にコンバーターをバインドできないことに注意してください。 しかし、このような問題は、たとえばコントロールの添付プロパティを使用して、対応するバインディング拡張機能を作成することで解決することもできます。



 <ToggleButton a:SourceKey="MyToogleButton">
      
      





 <BooleanConverter x:Key="BindableConverter" OnTrue="Value1" OnFalse="Value2" OnNull="{RemoteBinding SourceKey=MyToogleButton, Path=IsChecked}"/>
      
      





さらに、コントロールとコンバーターが同じビューにない場合でも、このオプションは機能します! メモリリークが発生しないように、実装に注意し、ストレージの制御に弱い参照を使用する必要があります。



スイッチコンバーター



多くの場合、大規模プロジェクトでは、同じタイプの多くの異なるタイプのコンバータークラスを作成する必要があります。そのロジックは、さまざまなEnumsなどのif-elseおよびswitchステートメントの動作に非常に似ています。 しかし、実際には、そのような場合、ユニバーサルスイッチコンバーターの使用に限定するだけで十分です。



 <SwitchConverter Default="ResultValue0" x:Key="ValueConverter1"> <Case Key="KeyValue1" Value="ResultValue1"/> <Case Key="KeyValue2" Value="ResultValue2"/> </SwitchConverter>
      
      





さらに、このコンバーターのプロパティ( Case構造を含む)はDependencyです 。つまり、 StoreBindingを使用してバインドに使用できます。 さらに、キーがオブジェクト自体の値ではなく、そのタイプである場合、 タイプモードがサポートされます。



 <SwitchConverter TypeMode="True" Default="{StaticResource DefaultDataTemplate}" x:Key="InfoConverter"> <Case Type="local:Person" Value="{StaticResource PersonDataTemplate}"/> <Case Type="local:PersonGroup" Value="{StaticResource PersonGroupDataTemplate}"/> </SwitchConverter>
      
      





このようなコンバーターは、後者がサポートされていない場合でも、 DataTemplateSelectorとして簡単に適用できることがわかりました! Switch Converterの汎用性により、膨大な数のケースに対応できます。少し想像力を働かせればよいだけです。



 <c:SwitchConverter Default="{StaticResource ControlTemplate0}" x:Key="TemplateSelectorConverter"> <m:Case Key='Value1' Value="{StaticResource ControlTemplate1}"/> <m:Case Key='Value2' Value="{StaticResource ControlTemplate2}"/> </c:SwitchConverter>
      
      





 <ListBox ItemsSource="{Binding Items}"> <ListBox.ItemTemplate> <DataTemplate> <ContentControl Template="{Binding DataType, Converter={StaticResource TemplateSelectorConverter}}"/> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
      
      





グローバルリソース



コンバーターについて話しているので、コンバーターを使用して作業を整理する最適な方法を説明することは価値があります。 まず、最も一般的なものを別のリソースディクショナリに配置する必要があります。



 <!--AppConverters .xaml--> <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <BooleanConverter x:Key="NullToTrueConverter" OnNull="True" OnNotNull="False"/> <BooleanConverter x:Key="NullToFalseConverter" OnNull="False" OnNotNull="True"/> <BooleanConverter x:Key="NullToVisibleConverter" OnNull="Visible" OnNotNull="Collapsed"/> <BooleanConverter x:Key="NullToCollapsedConverter" OnNull="Collapsed" OnNotNull="Visible"/> <BooleanConverter x:Key="TrueToFalseConverter" OnTrue="False" OnFalse="True" OnNull="True"/> <BooleanConverter x:Key="FalseToTrueConverter" OnTrue="False" OnFalse="True" OnNull="False"/> <BooleanConverter x:Key="TrueToVisibleConverter" OnTrue="Visible" OnFalse="Collapsed" OnNull="Collapsed"/> <BooleanConverter x:Key="TrueToCollapsedConverter" OnTrue="Collapsed" OnFalse="Visible" OnNull="Visible"/> <BooleanConverter x:Key="FalseToVisibleConverter" OnTrue="Collapsed" OnFalse="Visible" OnNull="Collapsed"/> <BooleanConverter x:Key="FalseToCollapsedConverter" OnTrue="Visible" OnFalse="Collapsed" OnNull="Visible"/> <EqualsConverter x:Key="EqualsToCollapsedConverter" OnEqual="Collapsed" OnNotEqual="Visible"/> <EqualsConverter x:Key="EqualsToVisibleConverter" OnEqual="Visible" OnNotEqual="Collapsed"/> <EqualsConverter x:Key="EqualsToFalseConverter" OnEqual="False" OnNotEqual="True"/> <EqualsConverter x:Key="EqualsToTrueConverter" OnEqual="True" OnNotEqual="False"/> <AnyConverter x:Key="AnyToCollapsedConverter" OnAny="Collapsed" OnNotAny="Vsible"/> <AnyConverter x:Key="AnyToVisibleConverter" OnAny="Visible" OnNotAny="Collapsed"/> <AnyConverter x:Key="AnyToFalseConverter" OnAny="False" OnNotAny="True"/> <AnyConverter x:Key="AnyToTrueConverter" OnAny="True" OnNotAny="False"/> </ResourceDictionary>
      
      





次に、この辞書をApp.xamlのリソースに直接または間接的に含める必要があります。これにより、追加の手順を行わなくても、アプリケーションのほぼすべてのxaml-ファイルでメインコンバーターを使用できます。 アプリケーションのグローバルリソースへのこのような追加は、多かれ少なかれ一般的なものに役立ちます。色、ブラシ、パターン、スタイル-たとえば、アプリケーションのテーマを変更するメカニズムを非常に簡単に実装するのに役立ちます。



 <Application x:Class="Sparrow.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="Views/AppView.xaml"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <!--<ResourceDictionary Source="AppConverters.xaml"/>--> <ResourceDictionary Source="AppStore.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>
      
      





セット



非常に便利なトリックは、多くの場合に適用できるxamlのユニバーサルコレクションSetを使用することです。 これにより、「多階建ての構造」を避け、一般的なポイントを作成し、レイアウトをより正確にし、チームにいくつかの引数を渡すことができます。



 public class Set : ObservableCollection<object> { }
      
      







 <Set x:Key="EditMenuSet" x:Shared="False"> <MenuItem Header="{Localizing Undo}" Command="Undo"/> <MenuItem Header="{Localizing Redo}" Command="Redo"/> <Separator/> <MenuItem Header="{Localizing Cut}" Command="Cut"/> <MenuItem Header="{Localizing Copy}" Command="Copy"/> <MenuItem Header="{Localizing Paste}" Command="Paste"/> <MenuItem Header="{Localizing Delete}" Command="Delete"/> <Separator/> <MenuItem Header="{Localizing SelectAll}" Command="SelectAll"/> </Set>
      
      





 <MenuItem Header="{Localizing Edit}" ItemsSource="{StaticResource EditMenuSet}"/>
      
      







 <Set x:Key="ParameterSet"> <system:String>/Views/AnyView.xaml</system:String> <system:String>SecondParaneter</system:String> </Set>
      
      





 <Button Content="{Localizing GoToAnyView}" Command="{Context Key=GoTo}" CommandParameter="{StaticResource ParameterSet}">
      
      





ご清聴ありがとうございました!



著者のメッセージ



これらの記事がすべて、開発者にとって興味深く有用であることを願っています。 特に、提案された概念の相互の一貫性に留意したいと思います。それらはお互いを補完し、強化しているようです。 教材を十分に勉強している人は、それらを仕事に応用して感謝することができると思います。



この知識を隠したり、それを請求したりするのは愚かです。 おそらく、しばらくすると誰かがこれらのヒントをシンプルな形に保つのにどれだけのリソースが役立ったかを理解し、 Aero Frameworkライブラリの作成者に感謝したいと思うでしょう。寄付の詳細はこのページにあります 。 おそらく、研究をさらに深く掘り下げて、実際のプロジェクトのソースコードを購入することを望む人もいます (もちろん、個々の開発者にとってはコストは目に見えますが、企業にとってはわずかな料金です)。



したがって、無料でライブラリを使用する場合でも、同僚、友人、および対象者全員にライブラリを推奨してください! よろしくお願いします!



All Articles