0

MVVM を使用して WPF の DataGrid を子ナビゲーション プロパティ (EF) に 1:1 でバインドする

全て、

.Net 4 と EF 4.4 の使用 (DB ファースト)

EntityCollection "Entity1" への参照を含む ViewModel があります。

このエンティティは、エンティティ 2 と 1 対 1 の関係にあります。

私の問題は、1:many または many:many の関係を持つ他のエンティティにバインドできますが、Entity1.Entity2 にバインドするのに問題があるように見えることです。私の推測では、これは Entity2 がコレクションではないためであり、そのため WPF はこれをどう処理すべきかよくわかりません。

したがって、ObservableCollection を Entity1 クラス (1:1 の関係である Entity2 のインスタンスを 1 つだけ含む) に追加してこれにバインドする以外に、Entity1 を持つという私の目標を達成するためのより良い方法があるのではないかと考えていました。 .Entity2 を DataGrid に表示します (DB を再設計したり、最終的に 1 つのオブジェクトのみを含む不要なコレクションを作成したりする必要はありません)。

CollectionViewSource 内に Entity1.Entity2 を配置しようとしましたが、それは役に立たないようです。

ありがとう。

4

2 に答える 2

0

試行 1: エンティティ クラスを作成する T4 テンプレートで、NavigationProperty を次のように変更します。

public string NavigationProperty(NavigationProperty navigationProperty)
{
    var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType());

    return string.Format(
        CultureInfo.InvariantCulture,
        "{0}\n\n    {1}  {2}  {3}\n    {{\n      {4}get\n        {{\n           return _{3}; \n        }}\n        {5} set\n        {{\n          _{3}=value; OnSet{3}();\n        }}\n      }}\n\n    {6}",
        string.Format(CultureInfo.InvariantCulture, "{0} _{1};",_typeMapper.GetTypeName(navigationProperty.TypeUsage), _code.Escape(navigationProperty)),
        AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)),
        navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
        _code.Escape(navigationProperty),
        _code.SpaceAfter(Accessibility.ForGetter(navigationProperty)),
        _code.SpaceAfter(Accessibility.ForSetter(navigationProperty)),
        string.Format(CultureInfo.InvariantCulture, "partial void OnSet{0}();", _code.Escape(navigationProperty)));
}

次に、Entity1 クラスの一部を追加します。

Partial Class Entity1:EntityBase
{
    public SpecificObservableCollection<Entity2> Entity2_Observable
    {
        get;
        set;
    }

    partial void OnSetEntity2()
    {
        Misc_Observable.Add(Entity2);
    }
    public class SpecificObservableCollection<T> : ObservableCollection<T>
    {
        public Action<T> SetValue { get; set; }
        protected override void InsertItem(int index, T item)
        {
            if (item != null)
            {
                base.InsertItem(index, item);
            }
        }
        protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            base.OnCollectionChanged(e);
            if (this.Count>0)
                SetValue(this[0]);
        }
    }

    protected override void DoStuffOnAdd()
    {
            Entity2_Observable = new SpecificObservableCollection<Entity2>();
            Entity2_Observable.SetValue = a => _Entity2 = a;
    }
}

次に、EntityBase で:

public abstract class EntityBase
{
    EntityBase()
    {
        DoStuffOnAdd();
    }
    protected virtual void DoStuffOnAdd() { }
}

IValueConverter の場合 (1:1 の関係で多くのレコードを追加しないようにするため)

public class CanAddValueConverter : IValueConverter
{
   private Type _T;
   private DataGrid _dg;

   public void SetValues(DataGrid dg, Type T)
   {
       _T = T;
       _dg = dg;
   }

   public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
   {
       System.Collections.IEnumerable dgIS = value as System.Collections.IEnumerable;
       if (_dg != null && dgIS == _dg.ItemsSource)
       {
           if (_dg.Items.Count > 0)
               return _dg.Items.Count <= System.Convert.ToInt32(parameter) && _dg.Items[_dg.Items.Count - 1].GetType() != _T;
           else
               return true;
       }
       else
           return false;
   }
}

次に、CodeBehind で、DataGrid を IValueConverter および対応するエンティティ タイプに割り当てます。

于 2012-11-20T21:08:21.640 に答える