C # WPF Привязка данных и Datacontext - PullRequest
0 голосов
/ 22 ноября 2018

Я (новичок в C # и WPF и) пытаюсь связать данные из большего количества источников (свойства класса), и я немного сбит с толку из разных руководств и советов.Я хочу динамически добавлять User s в 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; }
}

Спасибо за любой совет.

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

Решение: Вам необходимо связать входные данные в классе модели (Пользователь) и использовать модель для вставки данных в список, как показано ниже

<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));
        }
    }
}
0 голосов
/ 22 ноября 2018

Во-первых, во-первых, WPF работает лучше всего, когда вы работаете с MVVM , общая идея заключается в реализации INotifyPropertyChanged , все элементы, которые вы добавляете к себе, изменяются, распространяются нарамки и обновите ваши представления.

При работе со списками используйте ObservableCollection .Если вы хотите добавить к нему элементы динамически, вам нужно будет изменить ObservableCollection.Для достижения наилучших результатов в вашем UserControl используйте DataTemplate для определенного типа для отображения отформатированной версии ваших значений.

Для второй части, показывающей последний добавленный элемент, естьВ этом случае лучше всего добавить новые элементы (Grid, Stackpanel и т. д.), которые могут содержать данные, использовать Binding, чтобы установить для его значения тот же контекст, что и у вашего списка (т. е. ObservableCollection), и создать Конвертер , который будет использовать ObservableCollection в качестве входных данных, внутри вашей конкретной реализации конвертера, просто добавьте последний элемент и отобразите его в желаемом элементе управления (для этого вы также можете использовать dataTemplate)

...