5

このリンクをたどって、動的な dataGrid を実装しました。

Converter を使用して からの値をバインドしていますExpandoObject。列には、学校の合計ユニット数などの値が表示されます。

Item      ItemCount DefaultSchool School1  School2 School3

X-Item    200       100           50       50      0

学校はいつでも動的に追加できます。ここで、School4 を 40 ユニットで追加すると、デフォルトの学校 (DefaultSchool = 60、School4 = 40) から同じものを差し引きます。

コンバーターでこの計算を行うことができ、ItemsSource にも更新された値が表示されますが、UI には反映されません。

で TextBox のLostFocusイベントを使用するとMyDataGrid.Items.Refresh、UI が更新されますが、フォーカスが失われるたびに、Web ページが更新されるように UI がちらつきます)。

現在の行を更新するだけです。私は を使用してExpandoObjectいるため、 を使用することはできませんINotifyPropertyChanged(私は信じていますか?)。このシナリオでは、どのようなアプローチが最適でしょうか?

では、UI を更新するにはどうすればよいでしょうか。

4

4 に答える 4

1

デフォルトの DataGridColumn には 1 回限りのバインドがあります。つまり、値を読み込んで表示するのは初回のみです。サイン バインドにはイベントの接続が必要であり、パフォーマンスのオーバーヘッドがほとんどないため、そのようにした可能性があります。同じ問題がありました。唯一の解決策は、以下に示すようにセル テンプレートを使用することです。

<DataTemplateGridColumn Header="DefaultSchool">
     <DataTemplateGridColumn.CellTemplate>
          <TextBlock Text="{Binding DefaultSchool}"/>
     </DataTemplateGridColumn.CellTemplate>
</DataGridTemplateColumn>

列を動的に生成している場合は、このようなものが必要になります。

var t = new DataTemplate();
t.VisualTree = new FrameworkElementFactory((typeof(TextBlock));
t.VisualTree.SetBinding(new Binding(columnName));

var c = new DataGridTemplateColumn();
c.CellTemplate = t;
c.Header = columnName;

dg.Columns.Add( c );
于 2012-10-27T08:07:02.187 に答える
1

これは実装しなくても問題ないと思います実装するためExpandoObject)。INotifyPropertyChanged

私が考えているのは、あなたの問題はINotifyCollectionChangedコンバーターの組み合わせと使用にあるということです。プロパティが変更されるとコンバーターが呼び出されますが、コレクションが変更されるとコンバーターは呼び出されません。これにより、アイテムがバインドされたコレクションに追加または削除されたときに UI が更新されなくなります。

この問題の詳細については、次の質問を参照してください。

コンバーターにブレークポイントを設定することで、それが本当に問題であるかどうかを確認し、新しい項目を追加するときにそれが呼び出されているかどうかを確認できます。それが実際に問題である場合は、コンバーターを使用せずにこれを回避するか、次のMultiValueConverterようにプロパティも受け取るCount(トリガーとしてのみ機能する) を使用することができます。

<DataGrid>
    <DataGrid.ItemsSource>
        <MultiBinding Converter="{local:MyConverter}">
            <Binding Path="Items" />
            <Binding Path="Items.Count" />
        </MultiBinding>
    </DataGrid.ItemsSource>
</DataGrid>
public class MyConverter : MarkupExtension, IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        // Your converter logic which will use values[0] (the bound collection).

        // Ignore anything else in the values[] array.
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}
于 2012-10-20T21:29:46.300 に答える
0

XAMLバインディングにMode=TwoWayがあることを確認してください。

INotifyCollectionChangedは、コレクション内のアイテムを追加/削除したときにバインディングが通知されるようにしますが、コレクション内のオブジェクト(オブジェクトDefaultSchool)を変更/更新した場合、INotifyCollectionChangedは役に立ちません。

コレクション内のそのクラスのオブジェクトの更新/変更についてバインディングに通知を受け取るには、SchoolクラスにINotifyPropertyChangedを実装する必要があります。

于 2012-10-22T07:04:09.903 に答える
0

このようにウィンドウまたはユーザーコントロールのデータコンテキストを設定してみてください。datacontext = this.datacontext であり、 itemsource には必要なデータへのパスがあります。データコンテキストを設定しないと、アイテムソースはオブジェクトにバインドできません。それでも問題が解決しない場合は、ItemSource でアイテムのデータ テンプレートを作成してみてください。そして最後に ObservableCollection を使用するので、それらの INotifyProperty を実装する必要はありません...

于 2012-10-23T21:43:56.733 に答える