0

MVVMプロジェクトを開始しましたが、正しいDataBindingでスタックしています。私のプロジェクトには次のものがあります。

次のようなDataContextとしてのViewModelを使用するUserControl。

public partial class TestUserControl: UserControl
{
   public TestUserControl()
   {
       this.DataContext = new TestUserControlViewModel();
   }
}

ViewModelコードは次のとおりです(BaseViewModelクラスにはPropertyChangedEventHandlerが含まれています):

public class TestUserControlViewModel : BaseViewModel
{
   public KrankenkasseControlViewModel()
   {}

   public IEnumerable<DataItem> GetAllData
   {
      get
      {
          IGetTheData src= new DataRepository();
          return src.GetData();
      }
   }
}

IGetTheDataは、DataContextへのインターフェイスです。

public interface IGetTheData
{
   IEnumerable<DataItem> GetData();
}

}

そして最後にDataRepositoryコード:

public class DataRepository : IGetTheData
{
   private TestProjectDataContext dax = new TestProjectDataContext();

   public IEnumerable<DataItem> GetData()
   {
       return (from d in this.dax.TestData
               select new DataItem
               {
                  ID = d.ID,
                  SomeOtherData = d.SomeOtherData
               });
   }
}

私のUserControlにはいくつかのTextBoxがありますが、正しくバインドするための最良の方法は何ですか?

よろしくお願いします。

4

3 に答える 3

3

編集:複数のテキストボックスに対してデータをバインドする

コメントを読んだ後、テキストボックスの例を詳しく説明します。

最初に重要なことは、ViewModelがビュー内のものをモデル化することです。これにより、ビューは必要な構造で必要なすべての情報を取得します。つまり、ビューに複数のテキストボスがある場合、ビューモデルにテキストボックスごとに1つずつ、複数の文字列プロパティが必要になります。

XAMLには、次のようなものがあります。

<TextBox Text="{Binding ID, Mode=TwoWay}" />
<TextBox Text="{Binding SomeOtherData, Mode=TwoWay}" />

そしてあなたのViewModelで

public class TestUserControlViewModel : BaseViewModel {
    private string id;
    private string someOtherData;

    public TestUserControlViewModel() {
        DataItem firstItem = new DataRepository().GetData().First();
        this.ID = firstItem.ID;
        this.SomeOtherData = firstItem.SomeOtherData;
    }

    public string ID {
        get {
            return this.id;
        }
        set {
            if (this.id == value) return;
            this.id = value;
            this.OnPropertyChangedEvent("ID");
        }
    }

    public string SomeOtherData {
        get {
            return this.someOtherData;
        }
        set {
            if (this.someOtherData == value) return;
            this.someOtherData = value;
            this.OnPropertyChangedEvent("SomeOtherData");
        }
    }
}

ここでは、対応するイベントを発生させるメソッドBaseViewModelがあると想定しています。OnPropertyChangedEventこれは、プロパティが変更されており、それ自体を更新する必要があることをビューに通知します。

Mode=TwoWayXAMLのに注意してください。つまり、どちらの側で値が変更されても、もう一方の側では変更がすぐに反映されます。したがって、ユーザーがTwoWay境界内の値を変更するTextBoxと、対応するViewModelプロパティが自動的に変更されます。また、その逆も同様です。プログラムでViewModelプロパティを変更すると、ビューが更新されます。

複数のデータ項目に対して複数のテキストボックスを表示する場合は、ViewModelにさらに多くのプロパティを導入し、それに応じてそれらをバインドする必要があります。たぶん、@ Haspemulatorがすでに答えているように、内部にListBox柔軟な数のesを含むaが解決策です。TextBox

コレクションコントロールに対するデータのバインド

TestUserControl私はあなたがListViewロードされたもののリストを表示するためのコントロール(のような)を持っていると思います。したがって、そのコントロールをViewModelのリストに対してバインドします。

<ListView ... ItemsSource="{Binding GetAllData}" ... />

まず、バインディングとは「データを読み取ってからViewModelを忘れる」ことを意味しないことを理解する必要があります。代わりに、ビューが続く限り、ビューをViewModel(およびそのプロパティ)にバインドします。この観点から、はよりAllDataもはるかに良い名前ですGetAllData(@Malcolm O'Hareに感謝します)。

これで、コード内で、ビューがプロパティを読み取るたびAllDataに、新しいDataRepositoryものが作成されます。バインディングのため、これは必要なことではありません。代わりにDataRepository、ビューの存続期間全体にわたって1つのインスタンスを作成します。これは、初期データの読み取りに使用され、基になるデータベースの場合は後でビューの更新に使用できます。変更(おそらくイベントを伴う)。

このような動作を有効にするには、AllDataプロパティのタイプをに変更しObservableCollectionて、変更が発生した場合にビューがリストを自動的に更新できるようにする必要があります。

public class TestUserControlViewModel : BaseViewModel
    private ObservableCollection<DataItem> allData;

    public TestUserControlViewModel() {
         IGetTheData src = new DataRepository();
         this.allData = new ObservableCollection<DataItem>(src.GetData());
    }

    public ObservableCollection<DataItem> AllData {
        get {
            return this.allData;
        }
    }

    public void AddDataItem(DataItem item) {
        this.allData.Add(item);
    }
}

これで、後で呼び出すAddDataItemと、ListViewが自動的に更新されます。

于 2013-01-22T21:05:40.133 に答える
2

あなたのプロパティ名が悪いです。GetAllDataではなくAllDataと呼ぶ必要があります。

コレクションを返すので、おそらく何らかのリストコントロール(ListBox、ListView)を使用する必要があります。

その場合、あなたはやっているでしょう

<ListBox ItemsSource="{Binding GetAllData}" />
于 2013-01-22T21:05:11.090 に答える
0

グーテンアベンド。:)すでに述べたように、コレクションを返すので、ListBoxを使用することをお勧めします。ObservableCollectionをキャッシュとして持つことについてのコメントも絶対に有効です。データを編集可能にする必要がある場合は、ItemTemplate内でTextBoxを使用する必要があることを付け加えておきます。

<ListBox.ItemTemplate>
    <DataTemplate>
        <TextBox Text={Binding SomeOtherData,Mode=TwoWay} />
    </DataTemplate>
</ListBox.ItemTemplate>

この場合、ユーザーがボックス内のテキストを編集すると、データはデータオブジェクトで更新されるため、後でデータベースに保存できます。

于 2013-01-22T21:13:37.917 に答える