摘要:如何从 UI 更新数据模型中的 Isdone 属性?
(我在谷歌上读到的没有任何帮助。我希望有一个简单的答案。)
我试图尽可能完整,只显示相关代码。
初始化时,ListView 的复选框正确显示为被数据库 Actiontaken 的值选中。
但是,当从 UI 中选中 Checkbox 时,不会命中 Isdone 属性的设置代码。
在 Visual Studio 2010 中,我将解决方案分为以下项目:
1.混沌数据,
2. Chaos.DataService,
3. 测试客户端。
Chaos.Data 使用带有部分类的 EntityFramework 从数据库提供数据。在此,我为单独的业务规则添加了一个单独的文件,其中包含:
namespace Chaos.Data
{
partial class Lab
{
private Boolean? isdone;
public virtual Boolean? Isdone
{
get
{
isdone = (Actiontaken == 1 || Actiontaken == 129) ? true : false;
return isdone;
}
set
{
if (this.isdone != value)
{
this.isdone = value;
this.Actiontaken = 1;
this.OnPropertyChanged("Isdone");
if (this.isdone == true) this.setallcheckbox("Isdone");
}
}
}
Chaos.DataService 是 WCF 服务。在此,我定义了:
namespace Chaos.DataService
{
[OperationContract]
public IEnumerable<Lab> GetAllLabs(String groupid, DateTime? encountertime)
{
if (encountertime == null) return null;
using (var context = new ChaosModel())
{
var query = from lab in context.Labs
where lab.Groupid == groupid && lab.Tposted.Date <= ((DateTime)encountertime).Date
select lab;
var result = context.CreateDetachedCopy(query.ToList());
return result;
}
}
}
TestClient 使用对 Chaos.DataService 的引用(...是的,为了安全起见,我已经更新了 TestClient 中的服务引用。) TestClient 的观点如下:
XAML
<ListView ItemContainerStyle="{StaticResource ItemContStyle}"
ItemsSource="{Binding Labs}"
HorizontalAlignment="Stretch"
Margin="12,99,0,103" Name="listViewLabs" VerticalAlignment="Stretch" >
<ListView.View>
<GridView>
<GridViewColumn Header="Done" Width="40">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Isdone, Mode=TwoWay}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
.................
C# 代码隐藏:
namespace Chaos.UI.View
{
public partial class PatientLabsWindow : Window
{
public PatientLabsWindow(EncounterDetail encounter)
{
InitializeComponent();
ViewModelPatientLabs vm = new ViewModelPatientLabs(encounter);
this.DataContext = vm;
vm.CloseAction = new Action(() => this.Close());
}
}
}
在 ViewModel 中,我定义了:
namespace Chaos.UI.ViewModel
{
class ViewModelPatientLabs : ViewModelBase
{
private ChaosServiceClient serviceClient = new ChaosServiceClient();
// Constructor
public ViewModelPatientLabs(EncounterDetail encounter)
{
this.Encounter = encounter;
}
private EncounterDetail encounter;
public EncounterDetail Encounter
{
get
{
return this.encounter;
}
set
{
this.encounter = value;
this.OnPropertyChanged("Encounter");
this.GetAllLabs();
}
}
private void GetAllLabs()
{
// consume the WCF service.
this.serviceClient.GetAllLabsCompleted += (s, e) =>
{
this.Labs = e.Result;
};
// call the WCF service -- Async
this.serviceClient.GetAllLabsAsync(Encounter.groupid, Encounter.tencounter);
}
private IEnumerable<Lab> labs;
public IEnumerable<Lab> Labs
{
get
{
return this.labs;
}
set
{
this.labs = value;
this.OnPropertyChanged("Labs");
}
}
}
}
如果我错过了什么,请告诉我。
再次重申,ListView 的复选框已从数据库模型正确更新。但是,从 UI 中 checkin 该框不会在添加的 Labs 业务类中为 Isdone 设置代码。
我怎样才能解决这个问题?有任何想法吗?
编辑: Lab 是 Chaos.Data 命名空间中定义的类。它是由 Telerik DataAccess 生成的
namespace Chaos.Data
{
public partial class Lab : INotifyPropertyChanged
{
......
}
}
为了不触及这个自动生成的文件,我将我自己的添加和一个单独的文件添加到部分类中,如上所示。
编辑:我对这一切都很陌生。我发现有趣的是,当在客户端项目中更新服务时,WCF 将我的部分类添加到 Lab 实体中,如下所示:
namespace Chaos.UI.ChaosService {
using System.Runtime.Serialization;
using System;
..............................
[System.Runtime.Serialization.OptionalFieldAttribute()]
private System.Nullable<bool> IsdoneField;
[System.SerializableAttribute()]
public partial class Lab : object, System.Runtime.Serialization.IExtensibleDataObject,
System.ComponentModel.INotifyPropertyChanged {....
...............
[System.Runtime.Serialization.OptionalFieldAttribute()]
private System.Nullable<bool> IsdoneField;
并且从 WCF 查询返回的 Labs 的类型为 IEnumerable<> 而不是可观察的集合。那么 View 绑定(bind)正在更新 WCF 中的字段并且永远不会被传输回模型的问题?
请帮助某人?
最佳答案
如果你想让 IsDone 的 setter 属性在被点击时触发,你需要让 Lab 实现 INotifyPropertyChanged并提出 PropertyChanged IsDone 的 setter 属性上的事件。
这是一个工作示例。
看法
<Window x:Class="WpfUserControl.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<ListView ItemsSource="{Binding Labs}" >
<ListView.View>
<GridView>
<GridViewColumn Header="Done" Width="40">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsDone, Mode=TwoWay}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
代码背后
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
}
public class MainWindowViewModel
{
public MainWindowViewModel()
{
Labs = new[] { new Lab { IsDone = true } };
}
public IEnumerable<Lab> Labs { get; set; }
}
public class Lab : INotifyPropertyChanged
{
private bool? _isDone;
public bool? IsDone
{
get { return _isDone; }
set
{
_isDone = value;
OnPropertyChanged("IsDone");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
关于wpf - 将 Checkbox IsChecked 绑定(bind)到 EntityFramework 在 MVVM 模式中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24816291/