我通过书籍学习WPF中的绑定。我写了这样的代码:
using System;
namespace WpfBinding {
enum SomeColors {
Red,
Green,
Blue,
Gray
}
}
和
using System;
namespace WpfBinding {
class TestItem {
SomeColors color;
public TestItem(SomeColors color) {
Color = color;
}
internal SomeColors Color {
get { return color; }
set { color = value; }
}
public override string ToString() {
return Color.ToString();
}
}
}
我的窗口的XAML:
<Window x:Class="WpfBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListBox x:Name="listBox" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" Margin="5"/>
<ComboBox x:Name="comboBox" HorizontalAlignment="Stretch"
VerticalAlignment="Top" Margin="5" Grid.Column="1"/>
</Grid>
</Window>
我尝试通过代码创建绑定:
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfBinding {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
// Data for listbox
TestItem[] items = new TestItem[] {
new TestItem(SomeColors.Red),
new TestItem(SomeColors.Green),
new TestItem(SomeColors.Green),
new TestItem(SomeColors.Red),
new TestItem(SomeColors.Blue),
new TestItem(SomeColors.Red),
};
// Create ObservableCollection item
ObservableCollection<TestItem> collection = new ObservableCollection<TestItem>(items);
listBox.ItemsSource = collection;// set data for listbox
comboBox.ItemsSource = Enum.GetValues(typeof(SomeColors)); // Get items from my enum
// Create bindings
Binding bind = new Binding();
bind.Source = listBox;
bind.Path = new PropertyPath("SelectedItem.Color");
bind.Mode = BindingMode.TwoWay;
comboBox.SetBinding(ComboBox.SelectedItemProperty, bind);
}
}
}
但是我的绑定没有用。为什么?
屏幕:
答案 0 :(得分:2)
我认为问题在于您的课程没有实施INotifyPropertyChanged
。
为了让绑定知道某个属性何时更改了它的值,您必须向其发送通知,然后使用INotifyPropertyChanged
执行此操作。
<强>更新强>
因此,您的列表框绑定到ObservableCollection
,它确实提供了更改通知,但仅到列表框中,并且只有在您添加或删除集合中的项目时才会这样。
您可能还想在visual studio(http://msdn.microsoft.com/en-us/library/dd409960%28v=vs.100%29.aspx)中启用WPF绑定跟踪信息,这可能有助于您弄清楚发生了什么。
我注意到的最后一件事是TestItem
类的Color属性标记为internal
。 WPF将无法访问该属性,除非它是public
。
答案 1 :(得分:2)
在调试时观察Visual Studio的“输出”窗口总是很有用!如果你看过那里,你会看到这个:
System.Windows.Data Error: 40 : BindingExpression path error: 'Color' property not found on 'object' ''TestItem' (HashCode=20856310)'. BindingExpression:Path=SelectedItem.Color; DataItem='ListBox' (Name='listBox'); target element is 'ComboBox' (Name='comboBox'); target property is 'SelectedItem' (type 'Object')
确切地说,只能使用公共属性进行绑定,所以
internal SomeColors Color
应该是
public SomeColors Color
答案 2 :(得分:2)
这是错误 -
System.Windows.Data Error: 40 : BindingExpression path error: 'Color' property
not found on 'object' ''TestItem' (HashCode=13974362)'.
BindingExpression:Path=SelectedItem.Color; DataItem='ListBox' (Name='listBox');
target element is 'ComboBox' (Name='comboBox'); target property is 'SelectedItem'
(type 'Object')
您需要设置属性Color
public
而不是internal
。
来自MSDN here -
您用作绑定的绑定源属性的属性必须 是你班级的公共财产。明确定义的接口 无法访问属性用于绑定目的,也不能保护, 没有基础的私有,内部或虚拟属性 实施
答案 3 :(得分:1)
谢谢大家。我编辑了我的代码:
using System;
using System.ComponentModel;
namespace WpfBinding {
public class TestItem : INotifyPropertyChanged{
SomeColors color;
public TestItem(SomeColors color) {
Color = color;
}
public SomeColors Color {
get { return color; }
set { color = value;
OnPropertyChanged("Color");
}
}
public override string ToString() {
return Color.ToString();
}
void OnPropertyChanged(String name) {
PropertyChangedEventHandler temp = PropertyChanged;
if (null != temp) {
temp(this, new PropertyChangedEventArgs(name));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
和
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfBinding {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
// Data for listbox
TestItem[] items = new TestItem[] {
new TestItem(SomeColors.Red),
new TestItem(SomeColors.Green),
new TestItem(SomeColors.Green),
new TestItem(SomeColors.Red),
new TestItem(SomeColors.Blue),
new TestItem(SomeColors.Red),
};
// Create ObservableCollection item
ObservableCollection<TestItem> collection = new ObservableCollection<TestItem>(items);
listBox.ItemsSource = collection;// set data for listbox
ObservableCollection<SomeColors> collection2 = new
ObservableCollection<SomeColors>(Enum.GetValues(typeof(SomeColors)).Cast<SomeColors>());
comboBox.ItemsSource = collection2; // Get items from my enum
// Create bindings
Binding bind = new Binding();
bind.Source = listBox;
bind.Path = new PropertyPath("SelectedItem.Color");
bind.Mode = BindingMode.TwoWay;
comboBox.SetBinding(ComboBox.SelectedItemProperty, bind);
}
}
}
请看屏幕,请: