Я играю с WPF и LINQ и придерживаюсь следующего пункта, не имея понятия о том, как показать одну запись, все примеры, которые я нашел, показывают, как представить список, но не один запись.
Я подготовил пользовательский элемент управления, который должен показать одну запись в то время, в моем примере клиента, показывая его Id, имя и фамилия, здесь:Binding single record
<UserControl x:Class="SportsClubsManagement.CustomersManagement.CustomerData"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="500">
<Grid DataContext="Binding Customer">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="Id" Height="30" Width="70" />
<TextBox Grid.Row="0" Grid.Column="1" Height="20" Width="70" Name="Id" Text="{Binding Path=Id}" />
<Label Grid.Row="1" Grid.Column="0" Content="Given Name" Height="30" Width="70" />
<TextBox Grid.Row="1" Grid.Column="1" Height="20" Width="70" Name="GivenName" Text="{Binding Path=GivenName}" />
<Label Grid.Row="1" Grid.Column="2" Content="Surname" Height="30" Width="70" />
<TextBox Grid.Row="1" Grid.Column="3" Height="20" Width="70" Name="Surname" Text="{Binding Path=Surname}" />
<Button Grid.Row="2" Grid.Column="0" Content="New record" />
<Button Grid.Row="2" Grid.Column="3" Content="Next record" />
<Button Grid.Row="2" Grid.Column="2" Content="Prev record" />
</Grid>
</UserControl>
Я также создал таблицу с несколькими записями и классом для представления клиента, который также реализует INotifyPropertyChanged.
[Table(Name = "Customers")]
public class Customer : INotifyPropertyChanged
{
#region Fields
private String id;
private String givenName;
private String surname;
#endregion
#region Properties
[Column(IsPrimaryKey=true, Storage="id", Name="Id")]
public String Id
{
get { return this.id; }
}
[Column(Storage="givenName", Name="GivenName")]
public String GivenName
{
get { return this.givenName; }
set {
if (this.givenName != value)
{
this.givenName = value;
this.OnPropertyChanged("GivenName");
}
}
}
[Column(Storage="surname", Name="Surname")]
public String Surname
{
get { return this.surname; }
set {
if (this.surname != value)
{
this.surname = value;
this.OnPropertyChanged("Surname");
}
}
}
#endregion
#region INotifyPropertyChanged Members"
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(String name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
#endregion
}
Теперь в коде позади пользовательского элемент управления У меня есть действительно простой код, который подключение к БД и получает запись:
public partial class CustomerData : UserControl
{
private int curCustSeqNum;
private Data.Customer customer;
public Data.Customer Customer
{
get
{
return customer;
}
set
{
this.customer = value;
}
}
private IQueryable<Data.Customer> custQuery;
public CustomerData()
{
InitializeComponent();
DataContext db = new DataContext(@"server=WIN-EL78137MUMS\SQLEXPRESS;database=PlayGround;integrated security=SSPI");
// Get a typed table to run queries.
Table<Data.Customer> Customers = db.GetTable<Data.Customer>();
//db.Log = Console.Out;
custQuery =
from cust in Customers
orderby cust.Id
select cust;
curCustSeqNum = 0;
Customer = custQuery.Skip(curCustSeqNum).Take(1).First();
}
}
Но как я могу связать с текстовыми полями для текущего выбранного Клиента ? Вы можете увидеть мое последнее предположение после определения ресурсов и т. Д. Но каждый раз, когда я что-то пропускаю. Я хотел бы знать, как я могу добиться этого в XAML и в коде. В основном после этого я смог бы использовать curCustSeqNum, чтобы перейти к следующей записи.
Кажется, что это работает, но только одним способом. Что я пропустил, что не позволяет ему писать изменения? Другой вопрос. Должен ли я удалить реализацию класса INotifyPropertyChanged из класса Customer, это кажется бесполезным? И последнее на данный момент - Какова цель «DataContext = this»; вы добавили в конструктор? без него это не сработает, насколько я понимаю, добавляет DataContext в пользовательский элемент управления, указав, что он должен выглядеть локально, но мы также указали DataContext для Grid, и это должно переписать DataContext родителя, не так ли? И огромное спасибо! – Jyrkka
Вы должны сохранить 'INotifyPropertyChanged' в классе' Customer', так как это будет необходимо для обновления пользовательского интерфейса, если какое-либо из значений изменится. Набор 'DataContext' в конструкторе сообщает' UserControl' искать локально таким образом, чтобы вы могли получить доступ свойство 'Customer',' DataContext' в 'Grid' устанавливает свой контекст для объекта Customer, это означает, что все, что на' Grid', может получить доступ только к свойствам из свойства 'Customer', все они должны работать TwoWay (кроме Id), устанавливающий «UpdateSourceTrigger» в TextBoxes, например: «Text =» {Binding GivenName, UpdateSourceTrigger = PropertyChanged} »' –
Насколько я понимаю, тогда мой последний вопрос касается перемещения «DataContext = this;» line out to XAML, я обнаружил, что для пользовательского управления можно указать DataContext = "{Binding RelativeSource = {x: Static RelativeSource.Self}}", и это работает, правильно ли это сделать? и есть ли другие способы сделать собственность доступной в XAML? – Jyrkka