7

DataContext が T のリストである別の UserControl に DataGrid を作成しようとしています。

コード ビハインドでは、リストを作成し、リストにデータを入力してから、データを入力しようとしている DataGrid がある UserControl のコンストラクターに送信します。

UserControl クラスは次のとおりです。

public partial class QuotePreview : UserControl
{
    private static SelectionList  previewList = new SelectionList();

    public SelectionList PreviewList
    {
        get { return previewList; }
    }

    public QuotePreview()
    {
        InitializeComponent();
    }

    public QuotePreview(SelectionList selectedOptions)
    {
        InitializeComponent();

        previewList = selectedOptions;

        QuotePreviewDataGrid.DataContext = previewList;
    }
}

Xaml は次のようになります。

<DataGrid Name="QuotePreviewDataGrid"
          AutoGenerateColumns="False" 
          ItemsSource="{Binding}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Model Number" Binding="{Binding ModelNumber}"/>
        <DataGridTextColumn Header="Description" Binding="{Binding Description}"/>
        <DataGridTextColumn Header="List Price per Unit" Binding="{Binding Price}"/>
    </DataGrid.Columns>
</DataGrid>

私は ItemSource も使用して設定しようとしました

QuotePreviewDataGrid.ItemsSource = PreviewList;

また、データ コンテキストと itemsource の両方を設定し、更新してみました。

QuotePreviewDataGrid.Items.Refresh();

アプリケーションの残りの部分でリストボックスに設定したデータバインディングは完全に機能します。リスト ボックスでは、itemsource を {Binding} に設定し、ListItems バインディングを {Binding Property} に設定しています。コードビハインドで設定されたリストボックスのデータコンテキスト。

ここのデータグリッドは同じ方法でセットアップされていますが、何らかの理由でグリッド内に何も表示されていません。

デバッガーを使用して情報の流れを監視すると、List of T、SelectionsList が作成され、データ グリッドがあるユーザー コントロールのコンストラクターに渡されることがわかります。DataContext が実際に設定されており、リストに項目が表示されていることがわかりますが、アプリケーションに戻ってデータ グリッドを表示しようとすると、空白になります。

どんな助けでも大歓迎です。この 1 日半の間、この問題に頭を悩ませようとしてきました。ありがとう!

アップデート

SelectionList は次のように設定されます。

public class SelectionList : List<Selection>
{
    public List<Selection> availableSelections = new List<Selection>();

    public List<Selection> AvailableSelections
    {
        get { return availableSelections; }
    }
}

Selection は次のように定義されます。

public class Selection : DependencyObject
{
    public bool IsChecked { get; set; }
    public string ModelNumber { get; set; }
    public string Description { get; set; }
    public string Price { get; set; }
}

アプリケーションが起動したら、既存の製品 (セレクション) のカタログを作成します。製品ファミリごとに 1 つの異なるタブで、製品リスト ボックスのデータ コンテキストは、カタログから取得した使用可能な製品で初期化されます。次に、ユーザーがどの製品を選択するかを保留して、その製品に関連付けられた使用可能なオプションまたは子選択が、適切なリスト ボックス、アクセサリ、および保証に取り込まれます。

ユーザーが必要なオプションを選択すると、ボタンをクリックして、上記で説明したデータ グリッドに入力することになっている選択した項目をプレビューします。

選択したオプションのリストを作成できますが、データ グリッドのデータ コンテキストを設定しようとしても何も表示されません。利用可能な選択肢のリストは、データ グリッドに対して実行しようとしているのと同じ方法で構築され、適切なデータ コンテキストに設定されますが、データ グリッドは自分の情報を表示したくありません。

アップデート

そのため、さらにデバッグした後、問題を少し絞り込みました。データバインディングは正常に機能します。私はそこに本当の問題はないと思います。ただし、現在発生している問題は、ユーザー コントロールの 2 つの異なるインスタンスであると思われるものですが、更新されたコピーではなく、元のインスタンスのみが表示されます。

これは、問題のデバッグに役立つようにいくつかの行を追加した、約からのクラスのコピーです。

public partial class QuotePreview : UserControl
{
    private SelectionList _selectionList;
    private SelectionList temp;

    public QuotePreview()
    {
        InitializeComponent();
        _selectionList = (SelectionList)this.DataContext;
    }

    private void QuotePreview_Loaded(object sender, RoutedEventArgs e)
    {
        _selectionList.SelectedOptions.Add(
            new Selection
            {
                ModelNumber = "this",
                Description = "really",
                Price = "sucks"
            });
    }

    public QuotePreview(SelectionList selectedOptions)
    {
        InitializeComponent();
        _selectionList = (SelectionList)this.DataContext;

        temp = selectedOptions;

        _selectionList.AddRange(selectedOptions);

        QuotePreview_Loaded();
    }

    private void QuotePreview_Loaded()
    {
        foreach (var options in temp.SelectedOptions)
        {
            _selectionList.SelectedOptions.Add(options);
        }

        QuotePreviewDataGrid.ItemsSource = _selectionList.SelectedOptions;
    }
}

デフォルト コンストラクターの実装は、ユーザー コントロール/タブがクリックされるたびに呼び出されます。これが発生すると、_selectionList がユーザー コントロールのデータ コンテキストに設定され、その後にデータ グリッドに行を追加する Loaded イベントが続きます。

データ グリッド ユーザー コントロールに追加するオプションを選択する別のユーザー コントロールで、追加するオプションのリストを作成するボタンをクリックし、作成したカスタム コンストラクターを呼び出します。コンストラクターが完了すると、私が作成したカスタム Loaded Event メソッドが呼び出され、選択したオプションが _selectionList に追加されます。

データ グリッド ユーザー コントロールをもう一度クリックすると、既定のプロセス全体が実行され、別の既定の行が追加されます。

タブに戻り、これらのオプションがもう一度欲しいと言ってデータグリッドに戻ると、デフォルトのプロセスが再び実行され、別のデフォルト行が追加されます。

ただし、最も興味深いのは、プロセス間のプロセスをクリアしていないため、両方の selectionLists ビルドが表示されることです。表示したいオプションのリスト ビルドと、デフォルト オプション ビルドのリスト ビルドが表示されます...

また、SelectionList は ObservableCollection を実装しています。

4

2 に答える 2

2

私はついに問題の解決策を思いつきました。

public static class QuotePreview
{
    public static ObservableCollection<PurchasableItem> LineItems { get; private set; }

    static QuotePreview()
    {
        LineItems = new ObservableCollection<PurchasableItem>();
    }

    public static void Add(List<PurchasableItems> selections)
    {
        foreach (var selection in selections)
        {
            LineItems.Add(selection);
        }
    }

    public static void Clear()
    {
        LineItems.Clear();
    }
}

public class QuoteTab : TabItem
{
    public ObservableCollection<PurchasableItem> PreviewItems { get; private set; }

    public QuoteTab()
    {          
        Initialize()

        PreviewItems = QuotePreview.LineItems;

        DataGrid.ItemSource = PreviewItems
    }
}
于 2013-04-09T03:26:40.273 に答える
0

変更してみてください:

QuotePreviewDataGrid.DataContext = previewList;

this.DataContext = previewList;

私の疑惑はItemsSource="{Binding}"、xamlのがコンストラクターのDataContextコードをオーバーライドしていることです。

PreviewListをUserControl全体のDataContextに変更することにより、DataGridのバインディングをItemsSource正しく評価できます。

ちなみに、MVVMデザインパターンの使用法とMVVMデザインパターンについて調べ始めObservableCollection<T>ます。最終的に発生する可能性のある問題はDataGrid、基になるリストが変更されたときに更新されないことです。これを使用すると、ObservableCollection<T>これが修正されます。

MVVMデザインパターンを使用すると、ロジックとデータ(この場合はリストとそのロード方法)を物理ディスプレイ(DataGrid)から適切に分離できます。

于 2013-02-27T22:24:49.063 に答える