Привязка элементов управления вкладки к СОБСТВЕННОСТИ коллекции ObservableCollection с поворотом
У меня есть TabControl
Я следовал выбранному здесь ответу на письмо. Дело в том, что в моем случае ExistingTabs - это не ObservableCollection, а свойство ObservableCollection:
Public Class TestData : INotifyPropertyChanged // and the required event handler is there also, not shown here
{
public TabItem tiTestTab {get; set;}
// another dozen properties
}
а также
public class ReportData
{
public static ObservableCollection<TestData> testData {get;set;}
// another dozen properties
}
Вот что я сделал:
<Window.Resources>
<CollectionViewSource x:Key="ExistingTabs" Source="{Binding Path=(local:ReportDataSet.testData), Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Window.Resources>
<TabControl>
<TabControl.ItemsSource>
<CompositeCollection>
<TabItem>SomeSpecialItem</TabItem>
<CollectionContainer Collection="{Binding Source={StaticResource ExistingTabs}}"/>
</CompositeCollection>
</TabControl.ItemsSource>
</TabControl>
Это, конечно, помещает testData во вкладки, а не в свойство tiTestTab.
Я в растерянности.
Предпочтительно, только XAML. Использование C# и Visual Studio 2013.
Благодарю.
1 ответ
Решение
XAML код:
<Window.Resources>
<local:CollectionConverter x:Key="collectionConverter" />
<CollectionViewSource x:Key="ExistingTabs" Source="{Binding Path=(local:ReportDataSet.testData), Converter={StaticResource collectionConverter}, UpdateSourceTrigger=PropertyChanged}"/>
</Window.Resources>
<TabControl>
<TabControl.ItemsSource>
<CompositeCollection>
<TabItem Header="test">
<StackPanel>
<Button Content="Add new item" Click="AddNewTabItem"></Button>
<Button Content="Remove last item" Click="RemoveLastItem"></Button>
</StackPanel>
</TabItem>
<CollectionContainer Collection="{Binding Source={StaticResource ExistingTabs}}" >
</CollectionContainer>
</CompositeCollection>
</TabControl.ItemsSource>
</TabControl>
Преобразователь:
public class CollectionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is ObservableCollection<TestData>)
{
return new ObservableCollection<TabItem>(((ObservableCollection<TestData>)value).
Select(q => q.tiTestTab));
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
ReportDataSet:
public class ReportDataSet
{
public static ObservableCollection<TestData> testData { get; set; }
static ReportDataSet()
{
testData = new ObservableCollection<TestData>();
testData.Add(new TestData()
{
tiTestTab = new TabItem()
{
Header = "test 1"
}
});
testData.CollectionChanged += (s, e) => { OnStaticPropertyChanged("testData"); };
}
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;
protected static void OnStaticPropertyChanged(string propertyName)
{
var handler = StaticPropertyChanged;
if (handler != null) handler(null, new PropertyChangedEventArgs(propertyName));
}
}
Код позади (для целей тестирования):
private void AddNewTabItem(object sender, RoutedEventArgs e)
{
ReportDataSet.testData.Add(new TestData()
{
tiTestTab = new TabItem()
{
Header = "test " + (ReportDataSet.testData.Count + 1)
}
});
}
private void RemoveLastItem(object sender, RoutedEventArgs e)
{
if (ReportDataSet.testData.Count == 0) return;
ReportDataSet.testData.Remove(ReportDataSet.testData.Last());
}
Надеюсь, поможет