3

バインディングが機能しません。エラーを検索しましたが、私の場合の修正方法がわかりません。

System.Windows.Dataエラー:1:タイプ「MyApplication.MyUserControl」と「MyApplication.Person」の間で「一方向」変換を実行するデフォルトのコンバーターを作成できません。BindingのConverterプロパティの使用を検討してください。BindingExpression:Path =; DataItem ='MyUserControl'(Name =''); ターゲット要素は'MyUserControl'(Name ='');です。ターゲットプロパティは「PersonInfo」(タイプ「Person」)です

System.Windows.Dataエラー:5:BindingExpressionによって生成された値はターゲットプロパティに対して無効です。; Value ='MyApplication.MyUserControl' BindingExpression:Path =; DataItem ='MyUserControl'(Name =''); ターゲット要素は'MyUserControl'(Name ='');です。ターゲットプロパティは「PersonInfo」(タイプ「Person」)です

基本的には、PersonクラスのObservableCollectionにバインドされているListViewです。

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public ObservableCollection<Person> PersonCollection { set; get; }

    public MainWindow()
    {
        PersonCollection = new ObservableCollection<Person>();
        InitializeComponent();
        PersonCollection.Add(new Person() { Name = "Bob", Age = 20 });
    }
}

MainWindow.xaml

<Window DataContext="{Binding RelativeSource={RelativeSource Self}}" xmlns:self="clr-namespace:MyApplication" x:Class="MyApplication.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ListView ItemsSource="{Binding PersonCollection}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <self:MyUserControl PersonInfo="{Binding}" />
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>
</Window>

MyUserControl.xaml.cs

public partial class MyUserControl : UserControl
{
    public static readonly DependencyProperty PersonProperty = DependencyProperty.Register("PersonInfo", typeof(Person), typeof(MyUserControl));

    public Person PersonInfo
    {
        get { return (Person)GetValue(PersonProperty); }
        set { SetValue(PersonProperty, value); }
    }

    public MyUserControl()
    {
        InitializeComponent();
    }
}

MyUserControl.xaml

<UserControl DataContext="{Binding RelativeSource={RelativeSource Self}}" x:Class="MyApplication.MyUserControl" 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">
<TextBlock Text="{Binding PersonInfo.Name}" />
</UserControl>

Person.cs

public class Person : INotifyPropertyChanged
{
    public int Age { set; get; }
    public string Name { set; get; }

    public event PropertyChangedEventHandler PropertyChanged;

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

3 に答える 3

3

なぜそんなに複雑にするのか理解できません。PersonInfoプロパティを使用せず、その DataContext を変更することなく、UserControl を簡単にバインドできます。

<UserControl x:Class="MyApplication.MyUserControl" 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"> 
    <TextBlock Text="{Binding Name}" /> 
</UserControl>

次に、明示的なバインドなしで UserControl を DataTemplate に配置します。その DataContext にはすでに Person オブジェクトが含まれています。

<DataTemplate>      
    <StackPanel>      
        <self:MyUserControl />      
    </StackPanel>      
</DataTemplate>      
于 2012-04-15T17:14:41.110 に答える
2

問題は解決しましたが、Binding コード全体が間違っているように思われるため、次の代替案を提案します。

すべてのバインディング ソース オブジェクトの基本クラスを用意する - ObservableObject.cs

public abstract class ObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        var handler = this.PropertyChanged;
        if (handler != null)
            handler(this, e);
    }

    protected void SetValue<T>(ref T field, T value, string propertyName)
    {
        if (!EqualityComparer<T>.Default.Equals(field, value))
        {
            field = value;
            this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }
    }
}

MainWindow のビュー モデルを用意する - MainWindowModel.cs

public class MainWindowModel : ObservableObject
{
    private readonly ObservableCollection<Person> personCollection = new ObservableCollection<Person>()
    {
        new Person() { Name = "Bob", Age = 20 }
    };

    public ObservableCollection<Person> PersonCollection
    {
        get { return this.personCollection; }
    }
}

MainWindow.xaml.csは基本的に空になりました。

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
}

MainWindow.xamlは、DataContext を新しい MainWindowModel インスタンスに設定します。

<Window x:Class="MyApplication.MainWindow" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:self="clr-namespace:MyApplication">
    <Window.DataContext>
        <self:MainWindowModel/>
    </Window.DataContext>
    <ListView ItemsSource="{Binding PersonCollection}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <self:MyUserControl/>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Window>

MyUserControl.xaml.csも基本的に空です (自動生成されたコードのみが含まれます)。

public partial class MyUserControl : UserControl
{
    public MyUserControl()
    {
        InitializeComponent();
    }
}

MyUserControl.xaml

<UserControl x:Class="MyApplication.MyUserControl" 
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <TextBlock Text="{Binding Name}"/>
</UserControl>

Person.cs

public class Person : ObservableObject
{
    private int age;
    private string name;

    public int Age
    {
        get { return this.age; }
        set { this.SetValue(ref this.age, value, "Age"); }
    }

    public string Name
    {
        get { return this.name; }
        set { this.SetValue(ref this.name, value, "Name"); }
    }
}
于 2012-04-15T17:26:05.317 に答える
1

UserControl XAML を次のように変更します。

<UserControl x:Class="MyApplication.MyUserControl"
             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">
    <TextBlock DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}"
               Text="{Binding PersonInfo.Name}" />
</UserControl>

ここでは、DataContext の問題についての適切な説明を示します。

于 2012-04-15T16:56:41.070 に答える