web-dev-qa-db-ja.com

カスタム依存関係プロパティへのバインド-再度

はい知っています。これは文字通り100万回尋ねられましたが、それでもわかりません。そのために残念。

タスク:これまでのようにxamlで使用できる、最も単純な依存関係プロパティを実装します。

<uc:MyUserControl1 MyTextProperty="{Binding Text}"/>

this 答えはかなり近いと思います。読みやすくするために、すべてのコードをここにコピーします(主に上記の回答から)。

<UserControl x:Class="Test.UserControls.MyUserControl1"
             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" 
             DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
        <!-- Text is being bound to outward representative property;
             Note the DataContext of the UserControl -->
        <TextBox Text="{Binding MyTextProperty}"/>
    </Grid>
</UserControl>

そして

public partial class MyUserControl1 : UserControl
{
    // The dependency property which will be accessible on the UserControl
    public static readonly DependencyProperty MyTextPropertyProperty =
        DependencyProperty.Register("MyTextProperty", typeof(string), typeof(MyUserControl1), new UIPropertyMetadata(String.Empty));
    public string MyTextProperty
    {
        get { return (string)GetValue(MyTextPropertyProperty); }
        set { SetValue(MyTextPropertyProperty, value); }
    }

    public MyUserControl1()
    {
        InitializeComponent();
    }
}

そして、これは私のMainWindow.xamlです。

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml" xmlns:uc="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel Orientation="Vertical">
        <uc:MyUserControl1 MyTextProperty="my text goes here"/>
        <Button Click="ButtonBase_OnClick" Content="click"/>
    </StackPanel>
</Window>

これまでのところ、すべてが機能します。しかし、私はこれがまったく役に立たないと思います。私が必要なのは

<uc:MyUserControl1 MyTextProperty="{Binding Text}"/>

DataContextを設定することでこれを変更できる(MVVMで通常行うように)

だから私は上記のように行を置き換え、次のようにコードを後ろに追加します:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        Text = "Initial Text";
        DataContext = this;
    }
    private string _Text;
    public string Text
    {
        get { return _Text; }
        set
        {
            if (value != _Text)
            {
                _Text = value;
                NotifyPropertyChanged("Text");
            }
        }
    }

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        Text = "clicked";
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

「最初のテキスト」も「クリックされた」も表示されません...だから私の質問は、部門を実装する方法です。プロパティを正しく使用する

<uc:MyUserControl1 MyTextProperty="{Binding Text}"/>

?助けてくれてありがとう。

23

Textプロパティは、UserControlのDataContextMainWindowにあります。

したがって、この行を変更します<uc:MyUserControl1 MyTextProperty="{Binding Text}"/>これに:

<uc:MyUserControl1 MyTextProperty="{Binding Text, ElementName=MyMainWindow}"/>

これは、MainWindowにあるText要素について話していることをBindingに伝えます。もちろん、この例ではElementNameを使用しているので、nameウィンドウMyMainWindow ...を使用します。

これをMainWindowに追加します。

<Window  Name="MyMainWindow" ..... />

ウィンドウに名前を付けない場合は、次のようにRelativeSource FindAncestorバインディングを使用できます。

<wpfApplication6:MyUserControl1 MyTextProperty="{Binding Text, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"/>

どちらの方法でも、ウィンドウのDataContextで 'Text'という名前のプロパティを検索するように求めています。

28
Blachshma