0

現在、WindowsPhoneアプリでいくつかのカスタムコントロールをバインドする際に問題が発生しています。通常、これは決して問題ではありませんが、どうやら私の心は今日これを理解することができません。

だから私は良いMVVMスタイルのセットアップをしています。ビューとビューモデルを含むページがあります。WebClientコールバックで、ビューのdataContextをViewModelのモデルのリストに割り当てます。これまでのところ、素晴らしくシンプルです...ビューでは、基本的にセルであるデータテンプレートにカスタムコントロールを含むリストボックスを作成しました。リスト。もう一度、ユーザーコントロールのdataContextをバインディングに設定しました。すべてのモデル値を通常のUI要素にバインドしても問題はありません。

サンプルは次のとおりです。

<Grid Grid.Column="0">
            <Image Source="{Binding SmallPath}" VerticalAlignment="Top"/>
        </Grid>

        <Grid Grid.Column="1">
            <StackPanel Margin="12,0,0,0">
                <TextBlock x:Name="MemberId_TextBlock" Text="{Binding MemberId}" FontSize="28"
                           Margin="0,-8,0,0"
                           Foreground="{StaticResource PhoneForegroundBrush}"/>
                <StackPanel Orientation="Horizontal" Margin="0,-11,0,0">
                    <TextBlock Text="{Binding DaysReported}" FontSize="42"
                               Margin="0,0,0,0"
                               Foreground="{StaticResource PhoneAccentBrush}"/>
                    <TextBlock Text="days" FontSize="24"
                               Margin="3,19,0,0"
                               Foreground="{StaticResource PhoneSubtleBrush}"/>
                </StackPanel>
            </StackPanel>
        </Grid>

これは私のユーザーコントロールにあり、ユーザーコントロールが格納されているビューは次のとおりです。

<Grid x:Name="LayoutRoot" Background="Transparent">
    <ListBox Name="TopSpotter_ListBox" ItemsSource="{Binding}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <!--<TextBlock Text="{Binding MemberId}"/>-->
                    <controls:TopSpotterItemControl DataContext="{Binding}"/>
                    <Grid Height="18"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

これで十分ですが、ビューで実行したいのは、特定のグリッドなどを表示するかどうかを決定するブール値などのモデルからのデータを設定することです。したがって、コントロールで依存関係プロパティを明示的に設定しようとすると、起動してたとえば、Getter/Settersでロジックを実行します。ただし、バインディングソースからこれらのカスタムオブジェクトを設定しようとすると、実際には設定されません。

動作するものは次のとおりです。

<controls:TopSpotterItemControl ChampVisibility="True">

この方法でChampVisibilityプロパティがトリガーされ、ユーザーコントロールの背後にあるコードで可視性を設定できます。

これが失敗するものですが、私は働きたいです:

<controls:TopSpotterItemControl ChampVisibility="{Binding IsChamp">

さらに、DataContextを{Binding}に設定しても、結果は変更されません。

このシナリオでは、IsChampは私のモデルの一部であり、このユーザーコントロールにバインドしたいと思います。これは、viewModelからのビューに設定されているdataContextに由来すると思います。カスタムプロパティを設定しなくてもバインディングが機能するように、これを取得するために何ができるかわかりません。

最後に、これが私のユーザーコントロールです。

public partial class TopSpotterItemControl : UserControl
{
    public string MemberId
    {
        get
        {
            return this.MemberId_TextBlock.Text;
        }
        set
        {
            this.MemberId_TextBlock.Text = value;
        }
    }

    public bool ChampVisibility {
        set
        {
            if (value)
            {
                this.Champ_Grid.Visibility = System.Windows.Visibility.Visible;
            }
        }
    }

    public static readonly DependencyProperty MemberNameProperty =
        DependencyProperty.Register("MemberId", typeof(string), typeof(TopSpotterItemControl), new PropertyMetadata(null));

    public static readonly DependencyProperty ChampVisibilityProperty =
        DependencyProperty.Register("ChampVisibility", typeof(bool), typeof(TopSpotterItemControl), new PropertyMetadata(null));

    public TopSpotterItemControl()
    {
        InitializeComponent();
    }
}

少し長蛇の列ができていて、この問題について明確にしたいと思います。私の1つのメジャーはこれまでのところハングアップしており、モデルの知識に依存するxamlでバインディングを設定するのではなく、xamlで明示的に設定された依存関係プロパティを介してユーザーコントロールにできるだけ多くのコントロールを抽象化したいと思います。ありがとう!

4

1 に答える 1

1

DependencyProperty の形式が正しくありません。(あなたのクラスや XAML で定義された Champ_Grid も表示されませんが、それは省略されていると思います)

DependencyProperty とは無関係であるため、コードで ChampVisibility = true を設定すると機能します。

DP のデフォルト値が無効であるため、簡単にわかります。これはコンパイルされますが、インスタンス コンストラクターは、呼び出された場合に例外を通過します。

新しい PropertyMetadata(null)

bool = null = 例外

どこかから GetValue(TopSpotterItemControl.ChampVisibilityProperty) を呼び出すと、上記のすべてを確認できます。

プロパティ変更ハンドラーでインスタンス フィールドを変更し、次のようにプロパティを宣言する必要があります。これは機能します。

public bool ChampVisibility
{
    get { return (bool)GetValue(ChampVisibilityProperty); }
    set { SetValue(ChampVisibilityProperty, value); }
}

public static readonly DependencyProperty ChampVisibilityProperty =
    DependencyProperty.Register("ChampVisibility ", typeof(bool), typeof(TopSpotterItemControl), new PropertyMetadata(true, (s, e) =>
{
    TopSpotterItemControl instance = s as TopSpotterItemControl;
    instance.Champ_Grid.Visibility = instance.ChampVisibility ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
}));

ちなみに、MemberId DependencyProperty も完全に間違っており、機能しません。

注: TextBox の Binding は、DataContext (モデル) にバインドされているため機能するため、おそらく正しい値が表示されます。ただし、UserControl の Dependency プロパティは決して設定されません。

Visual Studio で propdp コード スニペットを使用すると、依存関係プロパティの宣言の複雑さを気にする必要がなくなります。

依存関係プロパティの詳細については、こちらもご覧ください

于 2013-01-30T21:04:55.843 に答える