我来自Linux繁重的环境,在那里我用Python编写了大部分工具,但现在我处于windows繁重的环境中,需要与我的团队共享我的工具,有些需要GUI驱动所以我正在尝试学习C#/ WPF。我对数据绑定到后面的代码中的ObservableCollection感到困惑。我可以让它发挥作用,但我不理解为什么,这让我感到困扰。
我的代码很简单,我只是试图让基础工作正常工作,以便我可以继续使用更复杂的部分:
XAML:
<ListView x:Name="lvUrlList" HorizontalAlignment="Left" Height="441" Margin="15,62,0,0" VerticalAlignment="Top" Width="486" SelectionChanged="listView_SelectionChanged" ItemsSource="{Binding Path=urlList, ElementName=MainWindow1}">
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="{Binding domain}"/>
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
代码背后:
namespace ReferalScraper
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
//public ObservableCollection<Url> urlList { get; set; } // Method 1
public ObservableCollection<Url> urlList = new ObservableCollection<Url>(); // Method 2
public MainWindow()
{
// urlList = new ObservableCollection<Url>(); // Method 1
InitializeComponent();
urlList.Add(new Url() { domain = "www.test1.com" });
}
public class Url
{
public string domain { get; set; }
}
private void button_Click(object sender, RoutedEventArgs e)
{
urlList.Add(new Url() { domain = "www.test2.com" });
urlList.Add(new Url() { domain = "www.test3.com" });
}
}
}
用于创建和实例化ObservableCollection的未注释方法不起作用,代码编译但我得到输出错误:
System.Windows.Data Error: 40 : BindingExpression path error: 'urlList' property not found on 'object' ''MainWindow' (Name='MainWindow1')'. BindingExpression:Path=urlList; DataItem='MainWindow' (Name='MainWindow1'); target element is 'ListView' (Name='lvUrlList'); target property is 'ItemsSource' (type 'IEnumerable')
我明白这意味着它无法在MainWindow中找到urlList对象。但我不明白为什么它找不到它。
如果我切换到方法1并取消注释以下两行(并注释掉“方法2”部分),它可以正常工作:
public ObservableCollection<Url> urlList { get; set; }
...
public MainWindow(){
urlList = new ObservableCollection<Url>()
为什么声明需要{ get; set }
的ObserverableCollection?我不太清楚为什么我不能将我的ObservableCollection实例化为一个空的ObserverableCollection,就像我在方法2中一样。
我感觉非常密集,并且无法找到正确的术语,甚至接近回答我的问题。任何人都可以向一位不那么聪明的家伙解释我所缺少的东西吗?
我有一种感觉,这是一些C#的理解我错过了。
答案 0 :(得分:3)
{ get; set; }
语法将您的uriList
定义为属性(在这种情况下为auto-implemented property)。如果没有这个,uriList
只是一个字段。
WPF数据绑定无法绑定到字段。有关为何会出现这种情况,请参阅this related question进一步讨论。
通常在C#字段中通常不公开,属性是首选。这允许您在需要时更改get / set实现。另外,属性的命名约定是PascalCased(所以UriList
而不是uriList
)。
答案 1 :(得分:0)
当您尝试从另一个ElementName
的属性获取绑定的属性时,使用FramworkElement
绑定,这不是这里的情况,
首先需要:从MainWindow构造函数中的代码隐藏中正确设置DataContext
:
this.DataContext=this;
或来自Window
DataContext="{Binding RelativeSource={RelativeSource Self}}"
然后将UriList
声明为属性,以便它可以与绑定一起使用
private ObservableCollection<Url> _uriList = new ObservableCollection<Url()
{
new Url() { domain = "www.test2.com" }
};
public bool UrlList
{
get
{
return _uriList;
}
set
{
if (_uriList == value)
{
return;
}
_uriList = value;
}
}
并将绑定更改为以下内容:
ItemsSource="{Binding UrlList}