1

これはおそらくロケット科学の質問ではないので、初心者であることを許してください! 人の名前を設定するための UserControl があります(テスト目的では簡単です)。

PersonNameControl.xaml:

<UserControl x:Class="BindingPropagationTest.Controls.PersonNameControl"
             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" 
             mc:Ignorable="d" Width="120" Height="23" Margin="0,0,0,0"
             >
    <TextBox Name="TextBox" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</UserControl>

ご覧のとおり、「実際の」テキストボックスである TextBox が含まれています。コードビハインドはこんな感じ。

PersonNameControl.xaml.cs:

using System.Windows.Controls;
using System.Windows;
using System.Diagnostics;

namespace BindingPropagationTest.Controls
{
    public partial class PersonNameControl : UserControl
    {
        public static DependencyProperty nameProperty
            = DependencyProperty.Register("PersonName", typeof(string), typeof(PersonNameControl));

        public string PersonName
        {
            get
            {
                Debug.WriteLine("get PersonNameControl.PersonName = " + TextBox.Text);
                return TextBox.Text;
            }

            set
            {
                Debug.WriteLine("set PersonNameControl.PersonName = " + value);
                TextBox.Text = value;
            }
        }

        public PersonNameControl()
        {
            InitializeComponent();
        }
    }
}

MainWindow.xaml でユーザー コントロールを使用します。

<Window x:Class="BindingPropagationTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:my="clr-namespace:BindingPropagationTest.Controls"
        xmlns:items="clr-namespace:BindingPropagationTest.ComboBoxItems"
        Title="Testing binding in UserControl"
        Width="179" Height="310">
  <Canvas Height="241" Width="144">

        <Label Canvas.Left="11" Canvas.Top="10" Content="Name" Height="28" Padding="0" />
        <my:PersonNameControl x:Name="nameControl"
                Width="120" Height="23"
                HorizontalAlignment="Left" VerticalAlignment="Top"
                PersonName="{Binding name}"
                Canvas.Left="11" Canvas.Top="28" />

        <Label Canvas.Left="11" Canvas.Top="57" Content="Address" Height="28" Padding="0" />
        <TextBox Canvas.Left="11" Canvas.Top="75" Width="120" Text="{Binding address}"></TextBox>

        <Label Canvas.Left="11" Canvas.Top="103" Content="Age" Height="28" Padding="0" />
        <TextBox Canvas.Left="11" Canvas.Top="122" Height="23" Name="textBox1" Width="120" Text="{Binding age}" />

        <ComboBox Canvas.Left="11" Canvas.Top="173" Height="23"
                Name="comboBox1" Width="120" SelectionChanged="comboBox1_SelectionChanged">
            <items:PersonComboBoxItem age="41" name="Donald Knuth" address="18 Donut Street" Height="23" />
            <items:PersonComboBoxItem age="23" name="Vladimir Putin" address="15 Foo Street" Height="23" />
            <items:PersonComboBoxItem age="32" name="Mike Hammer" address="10 Downing Street" Height="23" />
        </ComboBox>
    </Canvas>
</Window>

ご覧のとおり、いくつかの通常の TextBoxes と一緒に。

MainWindow のコード ビハインド

MainWindow.xaml.cs:

using System.Windows;
using System.Windows.Controls;
using BindingPropagationTest.ComboBoxItems;

namespace BindingPropagationTest
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new Person();
        }

        private void comboBox1_SelectionChanged
            (object sender, SelectionChangedEventArgs e)
        {
            updateForm();
        }

        private void updateForm()
        {
            var item = (PersonComboBoxItem)comboBox1.SelectedItem;

            DataContext = new Person()
            { age = item.age, name = item.name, address = item.address };           
        }
    }
}

DataContext を「人」に設定したことがわかります。

Person.cs:

namespace BindingPropagationTest
{
    public class Person
    {
        public string name {get; set; }
        public int age { get; set; }
        public string address { get; set; }
    }
}

お気づきのように、私はこのような独自の ComboBoxItem を発明しました。PersonComboBoxItem.cs:

using System.Windows.Controls;
using System.Diagnostics;

namespace BindingPropagationTest.ComboBoxItems
{
    public class PersonComboBoxItem : ComboBoxItem
    {
        private string _name = "";
        public string name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
                Content = _name;
            }
        }

        public int age { get; set; }
        public string address { get; set; }

        public override string ToString()
        {
            Debug.WriteLine("name: " + name);
            return name;
        }
    }
}

このアプリケーションを実行すると、次のウィンドウが表示されます。

ここに画像の説明を入力

コンボボックス項目を選択すると、次のようになります。

ここに画像の説明を入力

ご覧のとおり、名前は入力されません。なぜですか?

4

1 に答える 1

2

あなたはほとんどそこにいます、あなたが変える必要があるいくつかのこと

依存関係のプロパティは次のように使用されます

    public static DependencyProperty NameProperty = DependencyProperty.Register(
    "Name",
    typeof(string),
    typeof(PersonNameControl));

    public string Name
    {
        get
        {
            return (string)GetValue(NameProperty);
        }
        set
        {
            SetValue(NameProperty, value);
        }
    }

依存関係のプロパティに必要な非常に厳密な規則があります。プロパティがNameと呼ばれる場合は、「NameProperty」と呼ばれる必要があります。また、プロパティは依存関係プロパティを設定して取得するだけです。

次のように、テキストボックスをユーザーコントロールのプロパティにバインドできます。

<UserControl x:Class="BindingPropagationTest.Controls.PersonNameControl"
         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" 
         x:Name="UserControl"
         mc:Ignorable="d" Width="120" Height="23" Margin="0,0,0,0"
         >
    <TextBox Text="{Binding ElementName=UserControl, Path=Name}" Name="TextBox" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</UserControl>

上部にx:Name = "UserControl"ディレクティブを追加しました。バインディングのElementNameと一致する限り、任意の名前を付けることができます。

コンボボックスへの入力方法に関する追加の注意事項

メインウィンドウにプロパティを追加できます

    private ObservableCollection<Person> _thePeople;
    public ObservableCollection<Person> ThePeople
    {
        get
        {
            if (_thePeople == null)
            {
                List<Person> list = new List<Person>()
                {
                    new Person() { name = "Bob" , address = "101 Main St." , age = 1000 },
                    new Person() { name = "Jim" , address = "101 Main St." , age = 1000 },
                    new Person() { name = "Mip" , address = "101 Main St." , age = 1000 },
                };
                _thePeople = new ObservableCollection<Person>(list);
            }
            return _thePeople;
        }
    }

次に、ユーザーコントロールで使用されるx:Nameディレクティブをメインウィンドウに追加できます。

x:Name="TheMainWindow"

その後、次のようにコンボボックスでデータテンプレートを使用できます

    <ComboBox ItemsSource="{Binding ElementName=TheMainWindow, Path=ThePeople}"
          Height="23"
          Name="comboBox1" Width="120" >
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding name}" />
                    <TextBlock Text="{Binding address}" />
                    <TextBlock Text="{Binding age}" />
                </StackPanel>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>

ObservableCollectionはコードビハインドで使用されていたため、コードビハインドが「ThePeople」コレクションにアイテムを追加または削除するたびに、コンボボックスは自動的にアイテムを追加または削除します。電話するだけ

ThePeople.Add(new Person());

コンボボックスには自動的に新しいエントリが入力されます

于 2012-07-04T17:14:14.813 に答える