wpf - 将 Checkbox IsChecked 绑定(bind)到 EntityFramework 在 MVVM 模式中不起作用

标签 wpf entity-framework wcf mvvm checkbox

摘要:如何从 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/

相关文章:

wpf - CUDA 与 Windows 窗体/WPF 的集成

wpf - WPF Modern UI 的 '#1' 中的 '/Content/LoremIpsum.xaml#1' 是什么意思?

c# - DecimalUpDown 直接编辑时不显示正确的值

c# - asp.net MVC5 - 依赖注入(inject)和 AuthorizeAttribute

wcf - 什么是 WCF 调度管道消息流

c# - 在 WPF 中保存单击按钮的用户颜色设置

c# - 为什么返回类型是 IdentityUser 而不是 ApplicationUser?

c# - 如何使用 Linq 选择列名

c# - MessageSecurityException 没有为具有 'http://...' 操作的消息指定签名消息部分

wcf - 为什么 Tcp 比 http 快?