我正在使用 MVVM 模式,开发我的 WPF 应用程序。我还使用 Entity Framework 作为ORM。这是我的模型( EF ):
public class User : BaseEntity
{
public string Name { get; set; }
public int OfficeId { get; set; }
public Office Office { get; set; }
}
public class Office : BaseEntity
{
public string Name { get; set; }
public int DepartmentId { get; set; }
public Department Department { get; set; }
public virtual ICollection<User> Users { get; set; }
}
public class Department : BaseEntity
{
public string Name { get; set; }
public virtual ICollection<Office> Offices { get; set; }
}
我们假设,我的上下文中有一个User
类的实例:
var userInstance = context.Get<User>().Single(user => user.ID == 1);
现在我想将此实例传递给我的View以对具体用户进行一些更改(例如,调用UserEditView
),因此我必须创建一个UserModel
类来处理根据MVVM的User
数据。所以,这就是我认为我必须在我的代码中编写的内容:
public class UserModel : ObservableObject
{
private User user;
public string Office Office
{
get
{
return this.user.Office.Name;
}
set
{
//what shoud I write Here??
if(value != user.Office)
{
user.Office=value;
OnPropertyChanged("Office");
}
}
}
}
我真的很沮丧!我应该怎么处理?有成千上万的例子,但它们很简单。我想知道我应该怎样做才能在我的EditView中创建一个ComboBox,其中列出了我的数据库中存在的所有办公室。办事处清单应取决于另一个Combobox,其中包含部门清单。
PS :当然,我知道实现这种行为的几种方法,但在这种情况下,我的代码似乎很丑陋而且无法维护。请帮忙。非常感谢!
答案 0 :(得分:1)
这取决于您的数据库架构。这是一些常见的建议(但可能还有很多其他建议)。
更新 - 1
XAML代码
<Grid x:Name="LayoutRoot">
<Grid.DataContext>
<someBindingExampleSoHelpAttempt:MainViewModel/>
</Grid.DataContext>
<ListView ItemsSource="{Binding Users}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate DataType="someBindingExampleSoHelpAttempt:UserModel">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="200"></ColumnDefinition>
<ColumnDefinition Width="50"></ColumnDefinition>
<ColumnDefinition Width="50"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Text="{Binding Name, UpdateSourceTrigger=LostFocus, Mode=TwoWay}"/>
<TextBox Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Text="{Binding LastName, UpdateSourceTrigger=LostFocus, Mode=TwoWay}"/>
<ComboBox Grid.Column="2"
IsTextSearchEnabled="True"
IsTextSearchCaseSensitive="False"
StaysOpenOnEdit="True"
TextSearch.TextPath="DepartmentName"
ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type ListView}}, Path=DataContext.Departments}"
SelectedValue="{Binding Department}"
DisplayMemberPath="DepartmentName"
IsEditable="True"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
<ComboBox Grid.Column="3"
IsTextSearchEnabled="True"
IsTextSearchCaseSensitive="False"
StaysOpenOnEdit="True"
IsEditable="True"
TextSearch.TextPath="OfficeName"
ItemsSource="{Binding OfficesCollection}"
SelectedValue="{Binding Office}"
DisplayMemberPath="OfficeName"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView></Grid>
虚拟机和型号
public class MainViewModel:BaseObservableObject
{
private DepartmentModel _selectedDepartment;
private OfficeModel _selectedOffice;
public MainViewModel()
{
Dal = new DataLayer();
Users = new ObservableCollection<UserModel>();
Departments = new ObservableCollection<DepartmentModel>(Dal.GetAllDepartments());
InitUsersCollection();
}
private void InitUsersCollection()
{
if(Departments == null) return;
Departments.ToList().ForEach(model =>
{
model.Offices.ToList().ForEach(officeModel =>
{
if (officeModel.Users == null) return;
officeModel.Users.ToList().ForEach(userModel => Users.Add(userModel));
});
});
}
public ObservableCollection<UserModel> Users { get; set; }
public ObservableCollection<DepartmentModel> Departments { get; set; }
private DataLayer Dal { get; set; }
}
public class DataLayer
{
public List<DepartmentModel> GetAllDepartments()
{
//pull and map your using your DB service
//For example:
return new List<DepartmentModel>
{
new DepartmentModel
{
DepartmentId = 1,
DepartmentName = "A",
Offices = new ObservableCollection<OfficeModel>
{
new OfficeModel
{
DepartmentId = 1,
OfficeName = "AA",
Users = new ObservableCollection<UserModel>(new List<UserModel>
{
new UserModel {Name = "Avicenna", LastName = "Abu Ali Abdulloh Ibn-Sino"},
new UserModel {Name = "Omar", LastName = "Khayyam"},
new UserModel {Name = "RAMBAM", LastName = "Moshe ben Maimon"}
})
},
new OfficeModel
{
DepartmentId = 1,
OfficeName = "AB",
Users = new ObservableCollection<UserModel>(new List<UserModel>
{
new UserModel {Name = "Leo", LastName = "Tolstoi"},
new UserModel {Name = "Anton", LastName = "Chekhov"},
})},
}
},
new DepartmentModel
{
DepartmentId = 2,
DepartmentName = "B",
Offices = new ObservableCollection<OfficeModel>
{
new OfficeModel
{
DepartmentId = 2, OfficeName = "BA",
Users = new ObservableCollection<UserModel>(new List<UserModel>
{
new UserModel {Name = "B", LastName = "O"},
new UserModel {Name = "B", LastName = "N"},
}),
},
new OfficeModel
{
DepartmentId = 2, OfficeName = "BB",
Users = new ObservableCollection<UserModel>(new List<UserModel>
{
new UserModel {Name = "John", LastName = "Walker"},
new UserModel {Name = "Gregory", LastName = "Rasputin"},
}),
},
}
},
new DepartmentModel
{
DepartmentId = 3,
DepartmentName = "C",
Offices = new ObservableCollection<OfficeModel>
{
new OfficeModel {DepartmentId = 3, OfficeName = "CA"},
new OfficeModel {DepartmentId = 3, OfficeName = "CB"},
new OfficeModel {DepartmentId = 3, OfficeName = "CC"}
}
}
};
}
}
public class OfficeModel:BaseObservableObject
{
private int _departmentModel;
private string _officeName;
private DepartmentModel _department;
private ObservableCollection<UserModel> _users;
public int DepartmentId
{
get { return _departmentModel; }
set
{
_departmentModel = value;
OnPropertyChanged();
}
}
public DepartmentModel Department
{
get { return _department; }
set
{
_department = value;
OnPropertyChanged();
}
}
public string OfficeName
{
get { return _officeName; }
set
{
_officeName = value;
OnPropertyChanged();
}
}
public ObservableCollection<UserModel> Users
{
get { return _users; }
set
{
_users = value;
OnPropertyChanged(()=>Users);
}
}
}
public class DepartmentModel:BaseObservableObject
{
private string _departmentName;
public string DepartmentName
{
get { return _departmentName; }
set
{
_departmentName = value;
OnPropertyChanged();
}
}
public int DepartmentId { get; set; }
public ObservableCollection<OfficeModel> Offices { get; set; }
}
public class UserModel:BaseObservableObject
{
private string _name;
private string _lastName;
private DepartmentModel _department;
private OfficeModel _office;
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged();
}
}
public string LastName
{
get { return _lastName; }
set
{
_lastName = value;
OnPropertyChanged();
}
}
public DepartmentModel Department
{
get { return _department; }
set
{
_department = value;
OnPropertyChanged();
OnPropertyChanged(()=>OfficesCollection);
}
}
public ObservableCollection<OfficeModel> OfficesCollection
{
get { return Department.Offices; }
}
public OfficeModel Office
{
get { return _office; }
set
{
_office = value;
OnPropertyChanged();
}
}
}
/// <summary>
/// implements the INotifyPropertyChanged (.net 4.5)
/// </summary>
public class BaseObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanged<T>(Expression<Func<T>> raiser)
{
var propName = ((MemberExpression)raiser.Body).Member.Name;
OnPropertyChanged(propName);
}
protected bool Set<T>(ref T field, T value, [CallerMemberName] string name = null)
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
OnPropertyChanged(name);
return true;
}
return false;
}
}
但请注意,这只是数百种方法之一。 如果你需要代码示例,这里的SO。 问候。