objectlistview (olv) を使用して、マスター レコードに依存する子属性のセットを表示しています。linqを使ったac#アプリです。行エディターとして olv を使用しません。代わりに、基になる子レコードを動的で詳細な非 wpf ダイアログにポップアウトします。olv の列のモデル アスペクトがオブジェクト (つまり、外部キー) に依存している場合、olv の表示は更新されません。
例えば、
olv 表示にはステータスのログが含まれており、1 つの列は「Log.Status」のようにオブジェクト「Log」に関連する「Status.Code」です。linqなので、「Log.StatusId」もlinq DataContextに存在します(ただし、olvに表示するように設定されていません)。「Log.StatusId」は編集ダイアログから正しく返され、「Log.Status」は編集ダイアログが終了した直後に正しく読み込まれます。また、linq は編集を正しく保存します。
私は olv の Invalidate() と BuildList() と数日分のフードゥーを試して失敗しました。これは通常の olv であり、rapidlistview や datalistview ではありません。任意の視点を歓迎します。
以下のコードは、外部キーの処理を強調しています。olv を使用していないユーザーの場合、olv は他のほとんどの Windows フォーム コントロールと同様に構成されます。
...
object old = DataService.Clone<object>(olv.SelectedObject);
// where old ~ reference base for changes to olv object - for state management and linq
object row = olv.SelectedObject;
// where row ~ object that receives edits and undergoes updates via linq
Dictionary<string, object> rowState = new Dictionary<string, object>();
// where ~ rowState<fieldName,originalValue>
RecordDetail dlg = new RecordDetail(GetUser(), master.GetType(), row, rowState);
// where ~ GetUser() & master.GetType() configure form RecordDetail
DialogResult dr = dlg.ShowDialog();
if (dr == DialogResult.OK)
{
if (row != null && rowState != null && rowState.Count > 0)
{
int id = DataService.GetPrimaryKeyValue(row);
if (id > 0) /// if not new
{
int pk = DataService.GetPrimaryKeyValue(old);
MultiState state = getChildState(olv); // olv.Tag contains state
foreach (KeyValuePair<string, object> change in rowState)
{
MethodInfo mi = old.GetType().GetMethod(DataService.LINQ_GET + change.Key);
object newValue = mi.Invoke(row, null);
bool ok = DataService.ManageMultiStateUpdate(ref state, pk, change.Key, newValue, change.Value, old);
/// INFO populate fk objects for olv // <== works ok
Type tdomain = DataService.GetForeignKeyTypeAsAliasSafe(old.GetType(), change.Key);
if (tdomain != null)
{
object fko = GetForeignKey(tdomain, change.Value);
mi = row.GetType().GetMethod(DataService.LINQ_SET + change.Key.Replace(DataService.LI_ID, ""));
object[] args = { fko };
mi.Invoke(row, args);
}
...
}
olv.BuildList(); // <== both this and olv.Invalidate() fail to display foreign key updates
...
}
...
}
...
}
...