7

xからyまでの時間枠の動的な列数を表示するXamDataGridを作成する必要があります。したがって、ユーザーがこれらの列を事前に作成するために何年を選択するかはわかりません。

通常、MVVM内では、XamDataGrid内の列に必要な数のプロパティを介してデータを入力するだけで、後者はそれらを自動生成します。

明らかに、Reflectionで何かおかしなことをしない限り、実行時にViewModel内にプロパティを作成することはできませんでした。

他にどのようにこれを達成しますか?

データグリッドのバインドされていないフィールドを作成し、コードで入力する必要がありますか?グリッドは読み取り専用であるため、この段階では双方向のバインディングは必要ないことに同意します...ただ大声で考えているだけです。

このアプローチは、MVVMパターンに違反することなく問題ありませんか?ありがとう

4

2 に答える 2

5

インデクサーを使用できます。

ViewModelの場合:

public MyVariableCollection RowData
{
    get { return new MyVariableCollection(this); }
}

MyVariableCollection:保護されたSomeRowViewModel viewModel;

public MyVariableCollection(SomeRowViewModel viewmodel)
{
    this.viewModel = viewmodel;
}

public object this[string name]
{
    get { return viewModel.GetRowColumnValue(name); }
}

簡潔にしようとしましたが、アイデアは、インデクサーが定義された新しいクラスがあり、次のようにバインドできるということです。

{Binding Path=SomeRowViewModelInstance.RowData["ColumnName"]}

データグリッドコントロールの列コレクションがバインドされます。各列の列テンプレートを設定して、問題の列にバインドできます。そのようなインデクサーでリテラル文字列を使用する必要はありません。

それが思考の糧となることを願っています-このルートに関する質問はコメントを残してください。


追加の考えのために編集してください:私はComponentModelカスタム名前空間を作成するためにcontents名前空間を使用しましたTypeDescriptor。かなり詳細ですが、オブジェクトを「表示」して、追加のプロパティまたはカスタムプロパティを持たせることができます。上で投稿したインデクサーメソッドよりもはるかに複雑ですが、行き詰まった場合は一見の価値があります。

于 2010-08-06T17:48:36.187 に答える
1

ユーザーが実行時にグリッドの列を定義できたため、同様の問題が発生しました。

xam datagridを含み、グリッドのモデル(つまりデータテーブル)をバインドするためにDataSource依存関係プロパティを公開するコントロールを作成しました。

ソースが変更されるたびに(PropertyChangedイベントとグリッドFieldLayoutInitializingイベントのイベントリスナーを追加できます)、グリッドはデータソースをクリアしてリセットすることで動的に再レン​​ダリングされました。

private void ReRenderGrid()
{
    XamDataGrid.FieldLayouts.Clear();
    XamDataGrid.ClearValue(DataPresenterBase.DataSourceProperty);
    XamDataGrid.DataSource = DataSource.Data.DefaultView;
}

列は、グリッドデータソースがリセットされた後にxamdatagridによって発生する次のイベントのイベントハンドラーによって再構成されます。

XamDataGrid.FieldLayoutInitializing += LayoutInitializing;

ハンドラ:

private void LayoutInitializing(object sender, FieldLayoutInitializingEventArgs e)
{
    const string deletebuttonstyle = "DeleteButtonStyle";
    const string requiredinputvalue = "RequiredInputValue";
    const string optionalinputvalue = "OptionalInputValue";
    const string outputvalue = "OutputValue";

    var fieldLayout = e.FieldLayout;
    fieldLayout.Fields.Clear();

    AddFields(DataSource.InColumns, requiredinputvalue, fieldLayout);
    AddSplitter(fieldLayout);
    AddFields(DataSource.OptionalInColumns, optionalinputvalue, fieldLayout);
    AddSplitter(fieldLayout);
    AddFields(DataSource.OutColumns, outputvalue, fieldLayout);

    AddUnboundField(fieldLayout, string.Empty, GetStyle(deletebuttonstyle));
}

私の場合、データソースにはユーザーが構成したすべての列が含まれていました。AddFieldsは、リストエントリごとに次のメソッドを呼び出します。

private void AddField(string name, Style style, FieldLayout fieldLayout)
{
    var field = new Field {Name = name};
    field.Settings.LabelPresenterStyle = style;
    field.Settings.CellValuePresenterStyle = GetStyle("StandardCellValueStyle");
    fieldLayout.Fields.Add(field);
}

AddSplitterとAddUnboundFieldは、同様の方法で実装されます。

于 2010-08-17T20:10:21.230 に答える