我的绑定不起作用。我搜索了错误,但我不明白如何在我的情况下解决它。
System.Windows.Data错误:1:无法创建默认转换器以在类型“MyApplication.MyUserControl”和“MyApplication.Person”之间执行“单向”转换。考虑使用Binding的Converter属性。 BindingExpression:路径=; DataItem ='MyUserControl'(Name =''); target元素是'MyUserControl'(Name =''); target属性是'PersonInfo'(类型'Person')
System.Windows.Data错误:5:BindingExpression生成的值对目标属性无效。 Value ='MyApplication.MyUserControl'BindingExpression:Path =; DataItem ='MyUserControl'(Name =''); target元素是'MyUserControl'(Name =''); target属性是'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));
}
}
答案 0 :(得分:3)
我不太明白为什么你会这么复杂。您可以轻松绑定UserControl而不使用PersonInfo
属性,也无需修改其DataContext。
<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>
答案 1 :(得分:2)
虽然您修复了问题,但您的整个绑定代码对我来说似乎不对,所以我提出了这个替代方案:
拥有所有绑定源对象的基类 - 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"); }
}
}
答案 2 :(得分: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问题的good explanation。