TabControlのItemsSourceプロパティがViewModelのコレクションにバインドされています。 コンテンツテンプレートはです。ListView - UserControl。すべてのタブはListViewコントロールを1つだけ使用します(のコンストラクタListViewは1回だけ呼び出されます)。問題は、すべてのタブに共通の視覚的な状態があることです。たとえば、あるタブの項目のサイズを変更すると、この変更はすべてのタブに表示されます。どのように個別のリストビュー各タブを作成すると同時に、ItemsSourceプロパティを使用しますか?Wpf TabControlすべてのタブで1つのビューしか作成しない
答えて
これを行う簡単な方法はありません。
問題はWPFテンプレートがあることです。これは、どのデータを後ろに置いても同じです。テンプレートの1つのコピーが作成され、UIツリー内でWPFがListViewModel
に出会うたびに、そのテンプレートを使用して描画されます。 DataContextにバインドされていないコントロールのプロパティは、変化するデータソース間で状態を保持します。
x:Shared="False"
(例:here)を使用できますが、タブを切り替えるとWPFが要求するたびにテンプレートの新しいコピーが作成されます。
falseに設定し、[
x:Shared
がある]、リソースに対する要求ではなく、すべてのリクエストに対して同一のインスタンスを共有するよりも、リクエストごとに新しいインスタンスを作成することなどのWindows Presentation Foundationの(WPF)リソース検索の動作を変更します。各TabControl.Items
は、各項目について、あなたのコントロールの新しいコピーを生成していますが、(これは仕様です)ItemsSource
プロパティを使用するときには発生しませんのためにあなたが本当に必要なもの
です。
あなたのアイテムのコレクションにバインドするカスタムDependencyPropertyを作成し、コレクション内の各アイテムに対してTabItem
とUserControl
のオブジェクトを生成することもできます。このカスタムDPでは、コレクション変更イベントを処理して、TabItemがコレクションと同期していることを確認する必要があります。
ここで私は一緒に遊んでいました。 ObservableCollectionへのバインディングやアイテムの追加/削除などの単純なケースでは機能していました。このようなXAMLから使用
public class TabControlHelpers
{
// Custom DependencyProperty for a CachedItemsSource
public static readonly DependencyProperty CachedItemsSourceProperty =
DependencyProperty.RegisterAttached("CachedItemsSource", typeof(IList), typeof(TabControlHelpers), new PropertyMetadata(null, CachedItemsSource_Changed));
// Get
public static IList GetCachedItemsSource(DependencyObject obj)
{
if (obj == null)
return null;
return obj.GetValue(CachedItemsSourceProperty) as IList;
}
// Set
public static void SetCachedItemsSource(DependencyObject obj, IEnumerable value)
{
if (obj != null)
obj.SetValue(CachedItemsSourceProperty, value);
}
// Change Event
public static void CachedItemsSource_Changed(
DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (!(obj is TabControl))
return;
var changeAction = new NotifyCollectionChangedEventHandler(
(o, args) =>
{
var tabControl = obj as TabControl;
if (tabControl != null)
UpdateTabItems(tabControl);
});
// if the bound property is an ObservableCollection, attach change events
INotifyCollectionChanged newValue = e.NewValue as INotifyCollectionChanged;
INotifyCollectionChanged oldValue = e.OldValue as INotifyCollectionChanged;
if (oldValue != null)
newValue.CollectionChanged -= changeAction;
if (newValue != null)
newValue.CollectionChanged += changeAction;
UpdateTabItems(obj as TabControl);
}
static void UpdateTabItems(TabControl tc)
{
if (tc == null)
return;
IList itemsSource = GetCachedItemsSource(tc);
if (itemsSource == null || itemsSource.Count == null)
{
if (tc.Items.Count > 0)
tc.Items.Clear();
return;
}
// loop through items source and make sure datacontext is correct for each one
for(int i = 0; i < itemsSource.Count; i++)
{
if (tc.Items.Count <= i)
{
TabItem t = new TabItem();
t.DataContext = itemsSource[i];
t.Content = new UserControl1(); // Should be Dynamic...
tc.Items.Add(t);
continue;
}
TabItem current = tc.Items[i] as TabItem;
if (current == null)
continue;
if (current.DataContext == itemsSource[i])
continue;
current.DataContext = itemsSource[i];
}
// loop backwards and cleanup extra tabs
for (int i = tc.Items.Count; i > itemsSource.Count; i--)
{
tc.Items.RemoveAt(i - 1);
}
}
}
その:
<TabControl local:TabControlHelpers.CachedItemsSource="{Binding Values}">
<TabControl.Resources>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Header" Value="{Binding SomeString}" />
</Style>
</TabControl.Resources>
</TabControl>
は、注意すべきいくつかのこと:
TabItem.Header
が設定されていないので、あなたはそれのためにバインディングをセットアップする必要がありますinTabControl.Resources
- DependencyProperty実装は、現在、新しいUserControlの作成をハードコードしています。テンプレートプロパティやおそらく別のDPを使用してUserControlを作成するように指示するなど、他の方法でやりたいことがあります
- もっとテストする必要があるでしょう...MM8 @
- 1. いくつかのタブを左に並べ、他のタブを右に並べる方法は? (wpfのTabControl)
- 2. WPF tabcontrolでのTabitemのタイプの作成
- 3. TabitemのDatatemplateがすべてのタブアイテムスペース(WPF Tabcontrol)をカバーしていない
- 4. WPF TabControlのタブの並び替え
- 5. WPF TabIndexがTabControlで機能しない
- 6. asp:マルチビューコントロール - 異なるタブではなく1つのタブですべてのビューを表示できます
- 7. WPF TabControlには常に2つのタブ行があります
- 8. Jquery UIタブ。 1つのタブでのみ動作するすべてのチェックボックスを選択してください
- 9. TabControl - タブ間のスクロール
- 10. iMacrosは1つのタブですべてのリンクを1つずつ開いていますが、新しいタブでは表示しません。
- 11. WPF TabControlでViewModelを有効にするTabItemコンテンツの作成
- 12. タブのすべてのビューが満たされていない
- 13. MVC複数のフォームが1つのビューで動作しない
- 14. 私のスタイルトグルボタンがTabControlの2番目のタブで機能しないのはなぜですか?
- 15. ボタンで選択したタブを変更する方法WPFでタブをクリックするヘッダーのボタンでTabControlをクリック
- 16. TabControlタブを中心にしないで循環する
- 17. UISplitViewを1つのビューでのみ作成できますか?
- 18. WPF MVVM DataGridとTabControlを持つマスター詳細ビュー
- 19. 左揃えのタブでTabControlパネルを作成するにはどうすればよいですか?
- 20. ビューを作成してすべてのテーブルで変更する
- 21. 画像ビューを作成し、私はこの1つのようなビューを作成するより
- 22. TabControlのパフォーマンスが悪いWPF
- 23. Excelブックの1つのタブからの値のみを使用して新しいファイルを作成する
- 24. すべてのCSSコードがWebBrowser WPFで動作しないC#
- 25. WPF TabControl with Materials Design(Dragablzなし)
- 26. WPFレイアウト:Tabcontrol内でテキストボックスを作成する
- 27. TabControlがVS2010で動作しない
- 28. Rails複数のビューを1つのビューで作成
- 29. VB.netでどのタブが選択されているかテストする方法TabControl
- 30. 2つのテーブルで1つのビューを作成する方法
など、ハンドラを変更することにより、メモリリークに問題があるのかどうかわからない、私はそれが間違って重複したリンクであると思います。この質問は、単一のアイテムを作成し、それらの背後にあるDataContextを交換するデフォルトではなく、各タブアイテムを表示するための個別のContentTemplateを作成することです。私は、これを強制するためのテンプレートプロパティがあると思うが、わからない。個人的には、私はそのようなデザインに注意したいと思います...あなたが作成/コントロールの複数のコピーを格納するだろう、それが表示されていない場合でも。サイズがそれほど重要な場合は、DataContextにプロパティを作成してバインドして、各タブの変更ごとに変更することができます。 – Rachel
私が考えていたプロパティは 'x:Shared =" False "'です(例[here](http://stackoverflow.com/a/3488396/302677))。これは本当に理想的ではありませんが、タブを選択するたびにUserControlの新しいコピーが作成されるので、サイズ変更のようなことは無関係に保たれません。テンプレートを使用してTabControlアイテムを作成する場合は、関心のあるすべてのプロパティを保存/バインドすることをお勧めします。ユーザーがタブを切り替えたときに使用したテンプレートと同じですが、DataContextが異なるため、すべてのバインディングが更新されます – Rachel
'ItemsSource'を使うのではなく、各項目の' .TabItems'をビルドするカスタムTabControl DependencyPropertyに変換しますか? – Rachel