C#WPF数据绑定和数据上下文

时间:2018-11-22 15:12:22

标签: c# wpf data-binding datacontext

我(C#和WPF的新手)试图绑定来自更多来源(类属性)的数据,并且对不同的指南和建议有些困惑。我想在User中动态添加userList,并同时显示例如最后一个插入和整个列表。这是在源代码中的不同地方完成的,但是很简单,例如在我的示例的构造函数中。我应如何以及在何处为这三个元素(myNamemyTitlemyUserList)设置绑定和数据上下文,以反映主类属性的变化?我应该调用每次函数来更新绑定目标,还是在编辑属性后设置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; }
}

谢谢您的建议。

2 个答案:

答案 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));
        }
    }
}