将选项卡控件项绑定到 ObservableCollection 的 属性
bounding tab control items to a PROPERTY of an ObservableCollection, with a twist
我有一个TabControl
我按照选择的答案 here 写了这封信。问题是,在我的例子中,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.
谢谢。
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();
}
}
报告数据集:
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());
}
希望,有帮助
我有一个TabControl
我按照选择的答案 here 写了这封信。问题是,在我的例子中,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.
谢谢。
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();
}
}
报告数据集:
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());
}
希望,有帮助