C# 如何从XAML访问代码中的对象
我是WPF新手,正在尝试了解如何使用数据绑定将窗口上的控件绑定到代码隐藏中的对象。我看到了一些关于从codebehind访问XAML对象的问题,但这不是我想要的。我已经知道怎么做了C# 如何从XAML访问代码中的对象,c#,wpf,xaml,data-binding,C#,Wpf,Xaml,Data Binding,我是WPF新手,正在尝试了解如何使用数据绑定将窗口上的控件绑定到代码隐藏中的对象。我看到了一些关于从codebehind访问XAML对象的问题,但这不是我想要的。我已经知道怎么做了 label1.Content = LabelText; listbox1.ItemsSource = ListItems; 我还看到了关于如何从XAML访问codebehind中的类的答案 <local:MyClass x:Key="myClass" /> 但我不知道如何将其应用于类的特定实例。这
label1.Content = LabelText;
listbox1.ItemsSource = ListItems;
我还看到了关于如何从XAML访问codebehind中的类的答案
<local:MyClass x:Key="myClass" />
但我不知道如何将其应用于类的特定实例。这是一个我正在尝试做的例子。“绑定”显然是不正确的。这就是我需要帮助的地方
public partial class MainWindow : Window
{
private string _labelText;
private List<string> _listItems = new List<string>();
public MainWindow()
{
InitializeComponent();
_labelText = "Binding";
_listItems.Add("To");
_listItems.Add("An");
_listItems.Add("Object");
}
public string LabelText
{
get { return _labelText; }
set { _labelText = value; }
}
public List<string> ListItems
{
get { return _listItems; }
set { _listItems = value; }
}
}
<Window x:Class="SO_Demo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SO Demo" Height="160" Width="225">
<Grid DataContext="MainWindow">
<Label x:Name="label1" Width="80" Height="25" Margin="12,12,0,0"
Content="{Binding Path=LabelText}"
HorizontalAlignment="Left" VerticalAlignment="Top" />
<ListBox x:Name="listbox1" Width="100" Height="60" Margin="12,44,0,0"
ItemsSource="{Binding Path=ListItems}" DisplayMemberPath="ListItems"
HorizontalAlignment="Left" VerticalAlignment="Top" />
</Grid>
</Window>
公共部分类主窗口:窗口
{
私有字符串_labelText;
私有列表_listItems=新列表();
公共主窗口()
{
初始化组件();
_labelText=“绑定”;
_列表项。添加(“至”);
_列表项。添加(“An”);
_添加(“对象”);
}
公共字符串标签文本
{
获取{return\u labelText;}
设置{u labelText=value;}
}
公共列表项目
{
获取{return\u listItems;}
设置{u listItems=value;}
}
}
我读过的书和教程听起来应该很简单。我缺少什么?
无效
如果要引用该窗口,必须:
<Window x:Name="MyWindow">
<Grid DataContext="{Binding ElementName=MyWindow}"/>
</Window>
或
虽然您可以通过尝试的方式将
数据直接绑定到类,但这并不是通常的做法。建议的方法是创建一个对象(ViewModel),该对象聚合了您希望在UI中显示的所有模型数据,然后将该ViewModel设置为视图的DataContext
(本例中为窗口)。我建议阅读有关MVVM的内容,这是大多数WPF应用程序的构建方式。但是下面的例子可以让你开始
以下是一个基于上述示例的简单示例:
视图模型
public class MyViewModel : INotifyPropertyChanged
{
private string _title;
private ObservableCollection<string> _items;
public string LabelText
{
get { return _title; }
set
{
_title = value;
this.RaisePropertyChanged("Title");
}
}
public ObservableCollection<string> ListItems {
get { return _items; }
set
{
_items = value; //Not the best way to populate your "items", but this is just for demonstration purposes.
this.RaisePropertyChanged("ListItems");
}
}
//Implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
查看(窗口)
和DisplayMemberPath=“ListItems”
应从列表框中删除。这是毫无意义的。属性将需要INotifyPropertyChanged
语义。好的,那么ListItems
也可能是一个ObservableCollection
(或者至少实现INotifyCollectionChanged
):-)Re:“如果要引用该窗口,您必须:我只是假设LabelText和ListItems是我的MainWindow类的成员,所以我需要这样做。“让我访问这些成员吗?”@JNygren不认为UI元素是“成员”。可视树就是(树),因此它有“节点”,而不是“成员”。绑定中的ElementName=MyWindow
引用了XAML中定义的x:Name=“MyWindow”
属性。它不知道类或成员名称。这很有帮助!我想我记得在某个地方读到过,源属性(和目标?)必须是依赖属性。这是真的吗?谢谢几乎-你已经把它倒过来了。源属性可以是任何公共属性。使用INotifyPropertyChanged接口,以便对源的更新将自动反映在目标中。目标确实需要是从属属性
。详细描述数据绑定
,并详细介绍源和目标。
public class MyViewModel : INotifyPropertyChanged
{
private string _title;
private ObservableCollection<string> _items;
public string LabelText
{
get { return _title; }
set
{
_title = value;
this.RaisePropertyChanged("Title");
}
}
public ObservableCollection<string> ListItems {
get { return _items; }
set
{
_items = value; //Not the best way to populate your "items", but this is just for demonstration purposes.
this.RaisePropertyChanged("ListItems");
}
}
//Implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public partial class MainWindow : Window
{
private MyViewModel _viewModel;
public MainWindow()
{
InitializeComponent();
_viewModel = new MyViewModel();
//Initialize view model with data...
this.DataContext = _viewModel;
}
}
<Window x:Class="SO_Demo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SO Demo" Height="160" Width="225">
<Grid>
<Label x:Name="label1" Width="80" Height="25" Margin="12,12,0,0" Content="{Binding Path=LabelText}"
HorizontalAlignment="Left" VerticalAlignment="Top" />
<ListBox x:Name="listbox1" Width="100" Height="60" Margin="12,44,0,0"
ItemsSource="{Binding Path=ListItems}"
HorizontalAlignment="Left" VerticalAlignment="Top" />
</Grid>
</Window>