Привязки внутри CompositeCollection - PullRequest
5 голосов
/ 24 сентября 2010

Я хочу создать TabControl с несколькими «статическими» TabItems (явно введенными в XAML) и несколькими динамически добавляемыми TabItems. Чтобы добиться этого, я попытался использовать CompositeCollection в качестве TabControl.ItemSource.

Пример кода:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        >
  <Window.Resources>
    <x:Array x:Key="SomeTexts" x:Type="sys:String">
      <sys:String>Text1</sys:String>
      <sys:String>Text2</sys:String>
    </x:Array>
  </Window.Resources>

  <TabControl>
    <TabControl.ItemsSource>
      <CompositeCollection>
        <TabItem Header="Test">
          <StackPanel>
            <TextBlock x:Name="MyText" Text="Blah" />
            <TextBlock Text="{Binding Text, ElementName=MyText}" />
          </StackPanel>
        </TabItem>
        <CollectionContainer Collection="{StaticResource SomeTexts}" />
      </CompositeCollection>
    </TabControl.ItemsSource>
  </TabControl>
</Window>

В этом примере есть один фиксированный элемент табуляции и три «динамических» элемента табуляции (обратите внимание, что SomeTexts здесь является фиксированным массивом просто для упрощения примера; в реальном коде это будет динамическая коллекция).

Пример работает за исключением привязки ElementName, которая не работает. Я полагаю, это потому, что CompositeCollection не является Freezable (см. Также Почему CompositeCollection не Freezable? ).

У кого-нибудь есть решение?

1 Ответ

1 голос
/ 27 января 2015

У меня был похожий сценарий.Чтобы решить эту проблему, я нашел следующую статью .

В этом посте объясняется, как создать замораживаемый прокси-объект, для которого можно установить контекст данных.Затем вы добавляете этот прокси как ресурс, на который можно ссылаться как статический ресурс.Смотрите следующее:

public class BindingProxy : Freezable
{
    public static DependencyProperty DataContextProperty = DependencyProperty.Register(
        "DataContext", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));

    public object DataContext
    {
        get { return GetValue(DataContextProperty); }
        set { SetValue(DataContextProperty, value); }
    }

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }
}

Это может быть использовано в вашем xaml следующим образом:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:y="clr-namespace:Namespace.Of.BindingProxy"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        >
  <Window.Resources>
    <x:Array x:Key="SomeTexts" x:Type="sys:String">
      <sys:String>Text1</sys:String>
      <sys:String>Text2</sys:String>
    </x:Array>
    <y:BindingProxy x:Key="Proxy" DataContext="{Binding}" />
  </Window.Resources>

  <TabControl>
    <TabControl.ItemsSource>
      <CompositeCollection>
        <TabItem Header="Test">
          <StackPanel>
            <TextBlock x:Name="MyText" Text="Blah" />
            <TextBlock Text="{Binding DataContext.SomeProperty, Source={StaticResource Proxy}}" />
          </StackPanel>
        </TabItem>
        <CollectionContainer Collection="{StaticResource SomeTexts}" />
      </CompositeCollection>
    </TabControl.ItemsSource>
  </TabControl>
</Window>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...