8

シリアルポートからのデータで数秒に1回更新されるUserControlを作成しました。このUserControlは非常に単純で、フィールド名のラベルと、フィールド値を含む別のラベルで構成されている必要があります。簡単なはずだと言いますが、うまくいきません。まったく更新されず、フィールド名も表示されません。

以下はコードです:

public partial class LabeledField : UserControl {

    public LabeledField() {
        InitializeComponent();
    }

    public string fieldName { 
        get { return fieldNameLabel.Content.ToString(); } 
        set { fieldNameLabel.Content = value; } 
    }

    public string fieldValue { 
        get { return (string)GetValue(fieldValueProperty); } 
        set { SetValue(fieldValueProperty, value); }
    }

    public static readonly DependencyProperty fieldValueProperty =
        DependencyProperty.Register(
            "fieldValue", 
            typeof(string), 
            typeof(LabeledField),
            new FrameworkPropertyMetadata(
                "No Data"
            )
        )
    ;
}

XAMLは次のとおりです。

<UserControl x:Class="DAS1.LabeledField" Name="LF"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel Orientation="Horizontal">
    <Label Width="100" Height="30" Background="Gray" Name="fieldNameLabel" />
    <Label Width="100" Height="30" Background="Silver" Name="fieldValueLabel" Content="{Binding fieldValue}" />
</StackPanel>

これが、UserControlを参照するウィンドウのXAMLです。最初のヘッダー:

<Window x:Class="DAS1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:me="clr-namespace:DAS1"
Title="Window1" Height="580" Width="780">

次に、UserControl自体:

<me:LabeledField fieldName="Test" Width="200" Height="30" fieldValue="{Binding businessObjectField}"/>

もっと具体的な質問を知っていれば、そうしますが、なぜこれが機能しないのか誰かに教えてもらえますか?

4

3 に答える 3

9

ユーザーコントロールのXAMLで、バインディングが誤って指定されていたことが判明しました。

元々は:

<Label Width="100" Height="30" Name="fieldValueLabel" Content="{Binding fieldValue}" />

しかし、fieldValueが属する要素を指定していませんでした。それはそうあるべきです(私のユーザーコントロールの名前が「LF」であると仮定します:

<Label Width="100" Height="30" Name="fieldValueLabel" Content="{Binding ElementName=LF, Path=fieldValue}" />
于 2009-07-21T14:43:18.027 に答える
5

コントロールのプロパティにバインドする場合は、バインディングでそのように指定する必要があります。DataContextバインディングは、ソースが明示的に指定されていない場合に関連して評価されるため、バインディングはコントロールにバインドされませんが、継承されたコンテキスト(バインドしているプロパティが欠落している可能性があります)にバインドされます。必要なものは次のとおりです。

<Label Width="100" Height="30" Name="fieldValueLabel"
       Content="{Binding Path=fieldValue, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DAS1.LabeledField}}}" />
于 2009-07-17T20:22:34.407 に答える
4

ユーザーコントロールの依存関係プロパティは実際には必要ありません。実際、コードビハインドで特別なことを行わずにユーザーコントロールを維持するように努める必要があります。そのためには、カスタムコントロールを使用する必要があります。

UserControlを次のように定義する必要があります(背後にコードはありません)。

<UserControl x:Class="DAS1.LabeledField"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel Orientation="Horizontal">
        <Label Width="100" Height="30" Name="fieldNameLabel" Content="{Binding fieldName}" />
        <Label Width="100" Height="30" Name="fieldValueLabel" Content="{Binding field}" />
</StackPanel>

次に、ビジネスオブジェクトがINotifyPropertyChangedを実装していることを確認します。これは、少なくともこれだけ変更しないと、ビジネスオブジェクトから効率的に更新できないためです。これfieldNameは、ラベルの表示名をビジネスオブジェクトのプロパティに自動的にバインドする方法の単なる例です。

次に、UserControlのDataContextがビジネスオブジェクトであることを確認します。

これはどのように機能しますか?Label.ContentプロパティはDependencyPropertyであり、それ自体のバインドをサポートします。ビジネスオブジェクトはINotifyPropertyChangedを実装しているため、バインディングの更新をサポートします。これがないと、一方の端でDependencyPropertyにバインドしたかどうかに関係なく、フィールドの値が変更されてもバインディングシステムに通知されません

また、このユーザーコントロールを他の場所で再利用する場合は、ビジネスオブジェクトの目的のインスタンスを目的のLabeledFieldコントロールのDataContextに配置するだけです。バインディングは、DataContextからそれ自体をフックします。

于 2009-07-17T22:14:33.353 に答える