コントロールを定義するかユーザー コントロールを定義するかに関係なく、関数 - バインディングを使用します。書かれた名前: 要素バインディング。これは、バインドされた要素がデータ同期を達成できることを意味します。著者の意見では、この機能の WPF への導入は本当に完璧です。プログラミングはより具体的です。特にMVVMモデルと組み合わせると完璧です。著者は学者ではありません。それを包括的に伝えるのは非現実的です。著者の経験からバインディングについて話しましょう。
最も一般的な使用方法は、ターゲット要素がコントロール上の DataContext オブジェクトであることです。以下のように:
<TextBlock Grid.Column="0" Text="{Binding DishName}" Style="{StaticResource TakingDishDishNameTextStyle}" />
DataContext この属性は FrameworkElement クラスにあります。言い換えれば、ほとんどのコントロールは独自の DataContext を持ちます。次に、通常は最外層の DataContext プロパティのみを設定します。 DataContext バインディングをより明確に理解するため。著者は簡単な例を作りました。作成者は、最も外側の Window の DataContext 値を設定します。同時に、DataContext 値も内部グリッドに設定されます。ただし、これらは同じオブジェクト タイプではなく、同じ属性を持っているだけです。
<Window x:Class="Wpf.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:aomi="http://aomiwpf.com/ModernUI"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local ="clr-namespace:Wpf"Title="MainWindow" Height="350" Width="525"><Window.DataContext><local:WindDataContext /></Window.DataContext><Grid><Grid.DataContext><local:GridDataContext /></Grid.DataContext><TextBlock Text="{Binding TestName}"></TextBlock></Grid></Window>
の実行結果は以下の通りです。
この実験により、標準バインディングメソッドの対象要素がDataContextであることが証明できました。現在バインドされている要素に最も近い DataContext を検索します。仮説を立ててみましょう。GridDataContext クラスのプロパティ TestName が TestName1 に置き換えられたらどうなるでしょうか?
1 public class GridDataContext : NotifyPropertyChanged 2 { 3 private string _testName1 ="GridDataContext"; 4 5 public string TestName1 6 { 7 set 8 { 9 10 if (this._testName1 != value)11 {12 this._testName1 = value;13 OnPropertyChanged("TestName1");14 }15 }16 get { return this._testName1; }17 }18 }
の実行結果は以下の通りです:
申し訳ありません!著者は、Window の DataContext のプロパティ TestName にアクセスしようと考えました。どうやらそうではないようです。また、最も近い DataContext 内でのみ検索することも説明されています。いちいち探しに行くつもりはありません。
上記の {Binding} を記述するだけで、現在の DataContext がバインドされることに注意してください。彼の属性というよりも。
開発プロセス中、私たちは要素が別の要素の属性にバインドできることを望むことがよくあります。別の要素の属性が変更される限り、要素も一緒に変更するように通知されます。このとき、次の方法を使用する必要があります。
{Binding ElementName=SomeThingName, Path=Text}
ElementName: 要素の名前を表します。
Path: 要素オブジェクトの属性を表します。
実際、私たちは質問を考えることができます。バインディングは一方の当事者にのみ影響しますか?これはバインディングで使用されるモードです。以下の通り
{Binding ElementName=SomeThindName, Path=Text,Mode=TwoWay}
TwoWay: ソース属性またはターゲット属性への変更により、もう一方の属性が自動的に更新されます。
OneWay: バインディング ソース (source) が変更されると、バインディング ターゲット (target) プロパティを更新します。
OneTime: アプリケーションの起動時またはデータ コンテキストの変更時にバインディング ターゲットを更新します。
OneWayToSource: ターゲット プロパティが変更されたときにソース プロパティを更新します。
上記の使用法は比較的一般的です。これも比較的簡単です。オープンソース プロジェクトのバインディング式を見てみましょう。以下の通り
はっきり見えるか分かりませんが。上記は、親ノードの Button の Foreground と現在の Path の Stroke がバインドされていることを意味します。メインキーはAncestorTypeです。父親のタイプを指定するために使用されます。 Mode は RelativeSourceMode タイプです。彼には4つの価値観があります。次のように。
PreviousData: データ リストに使用され、前のデータ項目を意味します。それがデータコレクションの上の表示です。コントロールは含まれていません。
TempulatedParent: テンプレートのバインドに使用されます。
Self: 要素自体の属性にバインドします。
FindAncestor: 親要素を検索するために使用されます。
このように説明すると、RelativeSourceは相対ソース要素を指定するために使用されることが理解できます。それが対象の要素です。
実は、上記の式を別の方法で書くことも可能です。つまり、親を制限するために使用される深さがもう 1 つ (AncestorLevel) あります。以下の通り
<Button Command="{Binding Source={x:Static SystemCommands.MinimizeWindowCommand}}" ToolTip="{x:Static modernui:Resources.Minimize}" Style="{StaticResource SystemButton}"> <Button.Content> <Grid Width="13" Height="12" RenderTransform="1,0,0,1,0,1"> <Path Data="M0,6 L8,6 Z" Width="8" Height="7" VerticalAlignment="Center" HorizontalAlignment="Center" Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="2" /> </Grid> </Button.Content></Button>
注: バインドされた値を変更したい場合は、コンバータを使用する必要があります。以下の通り
{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}, AncestorLevel=2}, Path=Name}
カスタムコントロールを開発する際、エクスプレッションを使用することがよくあります。以下の通り
{Binding ElementName=SomeThindName, Path=Text,Mode=TwoWay,Converter=XXXConverter}
上記の書き込みは単なる略語です。完全なリストは次のとおりです
Width="{TemplateBinding Width}"
上記の内容は、著者が最も使用しているものであると言えます。次に、他のコンテンツ ポイントのバインディングを見てみましょう。つまり、一般的ではない内容です。
1.StringFormat関数。 string.format 関数と同等です。例を挙げる。金額の前に「¥」を付けたい場合はご利用いただけます。以下の通り
如果不是这样子做的话,你就不得不给“¥”一个TextBlock来显示,或是MoneyText变成string类型,然后设置值里面加上¥。但是笔者这里却是double类型的。所以用StringFormat的功能有就可以完美的决解了显示“¥”的问题。
执行结果:
2.TargetNullValue的功能,用于绑定目标是一个null值的时候,要显示的内容。如下笔者给NullName赋null。
<TextBlock Text="{Binding NullName, TargetNullValue=aomi}" />
执行结果:
3.FallbackValue的功能,用于绑定目标是发生错误的时候,要显示的内容。如下
<TextBlock Text="{Binding NullName, FallbackValue=aomi}" />
执行结果笔者就不贴了。
文章最后。在来说明一个不常用的功能——PriorityBinding。这个功能笔者不好说。只能让读者们自行体会吧。他主要用于在加载时间比较多的时候,要显示的信息。比如显示“正在加载中...”。笔者做了例子吧。
Xaml:
<Window x:Class="Wpf.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:aomi="http://aomiwpf.com/ModernUI"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local ="clr-namespace:Wpf"Title="MainWindow" Height="350" Width="525"><Window.DataContext><local:MainViewModel /></Window.DataContext><Grid><TextBlock><TextBlock.Text><PriorityBinding><Binding Path="UserName" IsAsync="True"></Binding><Binding Path="LoadingName"></Binding></PriorityBinding></TextBlock.Text></TextBlock></Grid></Window>
ViewModel:
public class MainViewModel : NotifyPropertyChanged {private string _userName ="Haya";private string _loadingName = "正在加载中...";public string UserName {set{if (this._userName != value) {this._userName = value; OnPropertyChanged("UserName"); } }get { Thread.Sleep(7000);return this._userName; } }public string LoadingName {set{if (this._loadingName != value) {this._loadingName = value; OnPropertyChanged("LoadingName"); } }get { return this._loadingName; } } }
执行结果:
七秒后:
本章的内容比较简单。笔者只是讲述了常用的一些知识点。但是必不是说就这些了。例如Binding还关系到Xml的绑定和集合的绑定功能。读者们可以自行去找一下资料。
以上がWPF のバインディング式に関する簡単な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。