只能从 TabControl 的第一个 TabItem 迭代控件
Can only iterate controls from first TabItem of a TabControl
我是wpf的初学者。我将从两个选项卡中获取按钮数量。应该是5。但是,我只能从第一个选项卡中获取两个按钮。
我试过切换到tab2,然后找不到按钮。
你知道我如何从所有选项卡中获取所有控件吗?我要将事件绑定到每个选项卡中的所有 canvas 和按钮。
这是我的主窗口:
<TabControl Name="tabMain" ItemsSource="{Binding Tabs}">
<TabControl.ItemTemplate>
<!-- this is the header template-->
<DataTemplate>
<TextBlock
Text="{Binding Header}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate DataType="{x:Type local:MyTabItem}">
<ItemsControl ItemsSource="{Binding Content}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:MyTabItemCtrl}" >
<Button Content="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=PosX}" />
<Setter Property="Canvas.Top" Value="{Binding Path=PosY}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
MainWindow.xaml.cs:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var btns = UIHelper.FindVisualChildren<Button>(tabMain).ToList();
// btns == 2
}
视图模型:
public sealed class MyViewModel
{
public ObservableCollection<MyTabItem> Tabs { get; set; }
public MyViewModel()
{
Tabs = new ObservableCollection<MyTabItem>();
ObservableCollection<MyTabItemCtrl> ct1 = new ObservableCollection<MyTabItemCtrl>();
ct1.Add(new MyTabItemCtrl { Name = "aaa", Age = 5, PosX=10, PosY=10 });
ct1.Add(new MyTabItemCtrl { Name = "bbb", Age = 5, PosX = 50, PosY = 10 });
ObservableCollection<MyTabItemCtrl> ct2 = new ObservableCollection<MyTabItemCtrl>();
ct2.Add(new MyTabItemCtrl { Name = "aaa", Age = 6, PosX = 10, PosY = 10 });
ct2.Add(new MyTabItemCtrl { Name = "bbb", Age = 6, PosX = 55, PosY = 10 });
ct2.Add(new MyTabItemCtrl { Name = "ccc", Age = 6, PosX = 100, PosY = 10 });
Tabs.Add(new MyTabItem { Header = "One", Content = ct1 });
Tabs.Add(new MyTabItem { Header = "Two", Content = ct2 });
}
}
public sealed class MyTabItem
{
public string Header { get; set; }
public ObservableCollection<MyTabItemCtrl> Content { get; set; }
}
public sealed class MyTabItemCtrl
{
public string Name { get; set; }
public int Age { get; set; }
public double PosX { get; set; }
public double PosY { get; set; }
}
只有当前可见的 TabItem
会加载到可视化树中,因此您将无法使用 UIHelper.FindVisualChildren
方法查找当前不可见的任何元素。
当您离开某个选项卡时,其内容将从可视化树中卸载。 So these Buttons
don't really exist when another tab is selected.
一个ContentTemplate
只是一个模板。它必须在创建任何实际 Button
元素并将其添加到可视化树之前实现。
我是wpf的初学者。我将从两个选项卡中获取按钮数量。应该是5。但是,我只能从第一个选项卡中获取两个按钮。
我试过切换到tab2,然后找不到按钮。
你知道我如何从所有选项卡中获取所有控件吗?我要将事件绑定到每个选项卡中的所有 canvas 和按钮。
这是我的主窗口:
<TabControl Name="tabMain" ItemsSource="{Binding Tabs}">
<TabControl.ItemTemplate>
<!-- this is the header template-->
<DataTemplate>
<TextBlock
Text="{Binding Header}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate DataType="{x:Type local:MyTabItem}">
<ItemsControl ItemsSource="{Binding Content}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:MyTabItemCtrl}" >
<Button Content="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=PosX}" />
<Setter Property="Canvas.Top" Value="{Binding Path=PosY}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
MainWindow.xaml.cs:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var btns = UIHelper.FindVisualChildren<Button>(tabMain).ToList();
// btns == 2
}
视图模型:
public sealed class MyViewModel
{
public ObservableCollection<MyTabItem> Tabs { get; set; }
public MyViewModel()
{
Tabs = new ObservableCollection<MyTabItem>();
ObservableCollection<MyTabItemCtrl> ct1 = new ObservableCollection<MyTabItemCtrl>();
ct1.Add(new MyTabItemCtrl { Name = "aaa", Age = 5, PosX=10, PosY=10 });
ct1.Add(new MyTabItemCtrl { Name = "bbb", Age = 5, PosX = 50, PosY = 10 });
ObservableCollection<MyTabItemCtrl> ct2 = new ObservableCollection<MyTabItemCtrl>();
ct2.Add(new MyTabItemCtrl { Name = "aaa", Age = 6, PosX = 10, PosY = 10 });
ct2.Add(new MyTabItemCtrl { Name = "bbb", Age = 6, PosX = 55, PosY = 10 });
ct2.Add(new MyTabItemCtrl { Name = "ccc", Age = 6, PosX = 100, PosY = 10 });
Tabs.Add(new MyTabItem { Header = "One", Content = ct1 });
Tabs.Add(new MyTabItem { Header = "Two", Content = ct2 });
}
}
public sealed class MyTabItem
{
public string Header { get; set; }
public ObservableCollection<MyTabItemCtrl> Content { get; set; }
}
public sealed class MyTabItemCtrl
{
public string Name { get; set; }
public int Age { get; set; }
public double PosX { get; set; }
public double PosY { get; set; }
}
只有当前可见的 TabItem
会加载到可视化树中,因此您将无法使用 UIHelper.FindVisualChildren
方法查找当前不可见的任何元素。
当您离开某个选项卡时,其内容将从可视化树中卸载。 So these Buttons
don't really exist when another tab is selected.
一个ContentTemplate
只是一个模板。它必须在创建任何实际 Button
元素并将其添加到可视化树之前实现。