gpt4 book ai didi

c# - WPF 数据绑定(bind)有问题

转载 作者:行者123 更新时间:2023-11-30 18:29:24 24 4
gpt4 key购买 nike

我有 2 个对象,一个客户和一个商店。有多个商店位置,每个客户都有一个名为 PreferredStoreId(int?)的属性,它与商店的 Id(int)相关。

在 WPF 应用程序中,我试图构建一个允许编辑客户的表单。此表单上存在一个组合框,其中填充了商店,用作显示当前设置的 PreferredStore 的方式和更改首选商店的方式。

我的问题是,虽然我可以填充组合框,但我无法在 Customer.PreferredId(设置为 UserControl 的数据上下文的对象)和组合框的 SelectedItem(存储对象)的 .Id 属性之间获得双向绑定(bind)。

这是我的 XAML,有助于理解:

<UserControl x:Class="ucCustomerEditor"
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"
xmlns:localViewModels="clr-namespace:ViewModels"
xmlns:qc="clr-namespace:QuickConverter;assembly=QuickConverter"
mc:Ignorable="d" d:DesignWidth="750" Height="334">
<UserControl.DataContext>
<localViewModels:CustomerViewModel x:Name="customerViewModel" />
</UserControl.DataContext>
<StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Height="26" Width="50" Content="Save" Margin="5,10" Click="UserAction_Save" />
<Button Height="26" Width="50" Content="Cancel" Margin="10,10" Click="UserAction_Cancel" />
</StackPanel>
<Grid Height="26" Margin="10" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="209"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBox Text="{Binding FirstName}" Height="23" Margin="10,0,0,0" TextWrapping="Wrap" VerticalAlignment="Top" HorizontalAlignment="Stretch" Grid.Column="1"/>
<Label Content="First Name:" Margin="10,0" VerticalAlignment="Top" FontWeight="Bold"/>
</Grid>
<Grid Height="26" Margin="10" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="209"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBox Text="{Binding LastName}" Height="23" Margin="10,0,0,0" TextWrapping="Wrap" VerticalAlignment="Top" HorizontalAlignment="Stretch" Grid.Column="1"/>
<Label Content="Last Name:" Margin="10,0" VerticalAlignment="Top" FontWeight="Bold"/>
</Grid>
<Grid Height="26" Margin="10" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="209"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBox Text="{Binding EmailAddress}" Height="23" Margin="10,0,0,0" TextWrapping="Wrap" VerticalAlignment="Top" HorizontalAlignment="Stretch" Grid.Column="1"/>
<Label Content="Email Address:" Margin="10,0" VerticalAlignment="Top" FontWeight="Bold"/>
</Grid>
<Grid Height="26" Margin="10" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="209"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBox Text="{Binding PhoneNumber}" Height="23" Margin="10,0,0,0" TextWrapping="Wrap" VerticalAlignment="Top" HorizontalAlignment="Stretch" Grid.Column="1"/>
<Label Content="Phone Number:" Margin="10,0" VerticalAlignment="Top" FontWeight="Bold"/>
</Grid>
<Grid Height="26" Margin="10" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="209"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ComboBox Name="cbPreferredStore"
ItemsSource="{Binding Stores}" DisplayMemberPath="DisplayName" Height="23" Margin="10,0,0,0" VerticalAlignment="Top"
HorizontalAlignment="Stretch" Grid.Column="1" SelectedValue="{Binding ElementName=customerViewModel, Path=PreferredStoreId}">
<ComboBox.DataContext>
<localViewModels:StoreListViewModel />
</ComboBox.DataContext>
</ComboBox>
<Label Content="Preferred Store:" Margin="10,0" VerticalAlignment="Top" FontWeight="Bold"/>
</Grid>
<Grid Height="26" Margin="10" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="209"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBox Text="{Binding Password}" Height="23" Margin="10,0,0,0" TextWrapping="Wrap" VerticalAlignment="Top" HorizontalAlignment="Stretch" Grid.Column="1"/>
<Label Content="Password:" Margin="10,0" VerticalAlignment="Top" Height="26" FontWeight="Bold"/>
</Grid>
</StackPanel>

StoreViewModel代码:

ublic class StoreViewModel : BaseViewModel
{
private enum Modes { CREATE, UPDATE }
private Modes _mode;
private Store _store;

public string DisplayName
{
get { return string.Format("{0} ({1})", this._store.LocationName, this._store.Id); }
}

public int Id
{
get { return this._store.Id; }
set
{
this._store.Id = value;
notifyPropertyChanged("Id");
notifyPropertyChanged("DisplayName");
}
}
public string LocationName
{
get { return this._store.LocationName; }
set
{
this._store.LocationName = value;
notifyPropertyChanged("LocationName");
notifyPropertyChanged("DisplayName");
}
}
public string ImageURL
{
get { return this._store.ImageURL; }
set
{
this._store.ImageURL = value;
notifyPropertyChanged("ImageURL");
}
}
public string AddressLine1
{
get { return this._store.AddressLine1; }
set
{
this._store.AddressLine1 = value;
notifyPropertyChanged("AddressLine1");
}
}
public string AddressLine2
{
get { return this._store.AddressLine2; }
set
{
this._store.AddressLine2 = value;
notifyPropertyChanged("AddressLine2");
}
}
public string AddressLine3
{
get { return this._store.AddressLine3; }
set
{
this._store.AddressLine3 = value;
notifyPropertyChanged("AddressLine3");
}
}
public string Suburb
{
get { return this._store.Suburb; }
set
{
this._store.Suburb = value;
notifyPropertyChanged("Suburb");
}
}
public string State
{
get { return this._store.State; }
set
{
this._store.State = value;
notifyPropertyChanged("State");
}
}
public string Postcode
{
get { return this._store.Postcode; }
set
{
this._store.Postcode = value;
notifyPropertyChanged("Postcode");
}
}
public string Country
{
get { return this._store.Country; }
set
{
this._store.Country = value;
notifyPropertyChanged("Country");
}
}
public string PhoneNumber
{
get { return this._store.PhoneNumber; }
set
{
this._store.PhoneNumber = value;
notifyPropertyChanged("PhoneNumber");
}
}
public string EmailAddress
{
get { return this._store.EmailAddress; }
set
{
this._store.EmailAddress = value;
notifyPropertyChanged("EmailAddress");
}
}

public static explicit operator StoreViewModel(EasyDayTea.Store store)
{
return new StoreViewModel(store) { _mode = Modes.UPDATE };
}

public StoreViewModel()
{
_store = new Store();
_mode = Modes.CREATE;
}

public StoreViewModel(Store store)
{
_store = store;
_mode = Modes.UPDATE;
}

public void Cancel()
{
if (_mode == Modes.CREATE)
{
_store = new Store() { };
}
else
{
EasyDayTea.EasyDayTeaClient client = new EasyDayTeaClient();
_store = client.FetchStore(App.AppUserTeaCredental, _store.Id);
client.Close();
}
notifyAll();
}

public void Save()
{
try
{
EasyDayTeaClient client = new EasyDayTeaClient();
if (_mode == Modes.CREATE)
{
client.AddStore(App.AppUserTeaCredental, ImageURL, LocationName, AddressLine1, AddressLine2, AddressLine3, Suburb, State, Postcode, Country, PhoneNumber, EmailAddress);
}
else
{
client.SetStore(App.AppUserTeaCredental, Id, ImageURL, LocationName, AddressLine1, AddressLine2, AddressLine3, Suburb, State, Postcode, Country, PhoneNumber, EmailAddress);
}
client.Close();

MessageBox.Show("Your customer was saved.");
if (_mode == Modes.CREATE)
{
_store = new Store();
notifyAll();
}
else
{
//do nothing.
}
}
catch (Exception ex)
{
MessageBox.Show("There was a problem saving your customer: \r\n" + ex.Message);
}
}

internal void notifyAll()
{
notifyPropertyChanged("Id");
notifyPropertyChanged("LocationName");
notifyPropertyChanged("ImageURL");
notifyPropertyChanged("AddressLine1");
notifyPropertyChanged("AddressLine2");
notifyPropertyChanged("AddressLine3");
notifyPropertyChanged("Suburb");
notifyPropertyChanged("State");
notifyPropertyChanged("Postcode");
notifyPropertyChanged("Country");
notifyPropertyChanged("PhoneNumber");
notifyPropertyChanged("EmailAddress");
notifyPropertyChanged("DisplayName");
}
}

StoreListViewModel代码:

public class StoreListViewModel : BaseViewModel
{
private List<StoreViewModel> _stores;

public List<StoreViewModel> Stores
{
get { return this._stores; }
set
{
this._stores = value;
notifyPropertyChanged("Stores");
}
}

public StoreListViewModel()
{
EasyDayTea.EasyDayTeaClient client = new EasyDayTea.EasyDayTeaClient();
_stores = client.GetStores(App.AppUserTeaCredental).Select(s => (StoreViewModel)s).ToList();
client.Close();
}
}

最佳答案

我假设 CustomerViewModel 中的 PreferredStoreId 属性正确地实现了 INotifyPropertyChanged界面。

如果是,那么您需要将 ComboBox 的 SelectedValue 更改为 SelectedItem,因为 SelectedItem 属性返回它当前选择的整个对象。然而,SelectedValuePath属性和 SelectedValue 一起用作 SelectedItem 属性的替代项,据我所知,这不是您的选择。

也在这里:

SelectedValue="{Binding ElementName=customerViewModel, Path=PreferredStoreId}"

不需要 ElementName,因为 CustomerViewModel 设置了默认分配的 DataContext

关于c# - WPF 数据绑定(bind)有问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23006097/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com