我(C#和WPF的新手)试图绑定来自更多来源(类属性)的数据,并且对不同的指南和建议有些困惑。我想在User
中动态添加userList
,并同时显示例如最后一个插入和整个列表。这是在源代码中的不同地方完成的,但是很简单,例如在我的示例的构造函数中。我应如何以及在何处为这三个元素(myName
,myTitle
和myUserList
)设置绑定和数据上下文,以反映主类属性的变化?我应该调用每次函数来更新绑定目标,还是在编辑属性后设置this.datacontext
?或者我应该绑定到某个函数(如果可能),该函数返回我需要的值?我对绑定到对象和数据上下文等的属性有些迷惑。这是我的一个例子:
<Window x:Name="Window" x:Class="WpfTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfTest">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<StackPanel>
<TextBox x:Name="myName" Text="" Grid.Column="1"/>
<TextBox x:Name="myTitle" Text="" Grid.Column="0"/>
</StackPanel>
<ListBox x:Name="myUserList">
</ListBox>
</Grid>
</Window>
和
public partial class MainWindow : Window {
public User myUser;
public Dictionary<int,User> userList= new Dictionary<int, User>();
public object SubWindow { get; private set; }
public MainWindow() {
newUser = new User();
newUser.Title = "John Doe";
newUser.Name = "Dr.";
this.userList.Add(index,newUser);
this.myUser=newUser;
InitializeComponent();
}
}
和
public class User
{
public String Name { get; set; }
public String Title { get; set; }
}
谢谢您的建议。
答案 0 :(得分:1)
首先是第一件事,WPF在使用MVVM时工作得最好,一般的想法是实现INotifyPropertyChanged,无论您添加的内容发生什么变化,都会传播到框架并进行更新您的意见。
使用列表时,请使用ObservableCollection。如果要向其中动态添加项目,则需要修改ObservableCollection。为了获得最佳结果,请在您的UserControl中为特定类型使用DataTemplate,以显示值的格式化版本。
对于第二部分,显示最后添加的项目,有几种解决方法,最好的方法是添加一个可以容纳数据的新Items(Grid,Stackpanel等),使用Binding设置将其值设为与列表相同的上下文(即ObservableCollection),并创建一个Converter,它将在特定转换器实现内将ObservableCollection用作输入,只需获取最后添加的项并将其显示在控件中想要(您也可以为此使用dataTemplate)
答案 1 :(得分:-1)
<Window x:Class="WpfRegistration.Listbox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfRegistration"
mc:Ignorable="d"
Title="Listbox" Height="450" Width="800">
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.15*"></RowDefinition>
<RowDefinition Height="0.85*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="63*"></ColumnDefinition>
<ColumnDefinition Width="26*"></ColumnDefinition>
<ColumnDefinition Width="109*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel>
<TextBox x:Name="myName" Text="" Grid.Column="1"/>
<TextBox x:Name="myTitle" Text="" Grid.Column="0"/>
</StackPanel>
<StackPanel>
<Button Height="23" Margin="50,40,0,0" Name="button1" VerticalAlignment="Top" HorizontalAlignment="Left" Width="76" Click="Button1_OnClick" >Add Item</Button>
</StackPanel>
<StackPanel>
<Button Height="23" Margin="140,40,10,12" Name="DeleteButton" VerticalAlignment="Top" Click="DeleteButton_Click">Delete Item</Button>
</StackPanel>
<ListBox Grid.Row="1" Grid.Column="0" BorderThickness="3" BorderBrush="Black" Margin="0,60,0,100" x:Name="myUserList">
</ListBox>
</Grid>
</Grid>
Xaml.cs
public partial class Listbox : Window
{
public Listbox()
{
InitializeComponent();
User newUser = new User();
newUser.Title = "John Doe";
newUser.Name = "Dr.";
this.myUserList.Items.Add(newUser.Title + newUser.Name);
}
private void Button1_OnClick(object sender, RoutedEventArgs e)
{
User newUser = new User();
newUser.Title = myTitle.Text;
newUser.Name = myName.Text;
myUserList.Items.Add(newUser.Name + " " + newUser.Title );
myTitle.Text=String.Empty;
myName.Text=String.Empty;
}
private void DeleteButton_Click(object sender, RoutedEventArgs e)
{
myUserList.Items.RemoveAt(myUserList.Items.IndexOf(myUserList.SelectedItem));
}
}
public class User
{
public string name;
public string title;
public String Name
{
get { return name; }
set
{
name = value;
OnPropertyChanged("name");
}
}
public string Title
{
get { return title; }
set
{
title = value;
OnPropertyChanged("title");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}