C# 在WPF中将TabItem强制转换为UserControl
我的主屏幕上有一个选项卡控件。它有不同的选项卡项。例如:C# 在WPF中将TabItem强制转换为UserControl,c#,wpf,casting,tabs,user-controls,C#,Wpf,Casting,Tabs,User Controls,我的主屏幕上有一个选项卡控件。它有不同的选项卡项。例如: <TabControl Name="mainTab" Padding="0" Margin="70,80,350,49"> <!--Left,Top,Right, Bottom--> <TabItem GotFocus="TabItem_Animals_GotFocus"> <TabItem.Header>
<TabControl Name="mainTab" Padding="0" Margin="70,80,350,49">
<!--Left,Top,Right, Bottom-->
<TabItem GotFocus="TabItem_Animals_GotFocus">
<TabItem.Header>
Animals
</TabItem.Header>
<ContentControl Margin="10">
<Frame Name="animalFrame" Source="AnimalWorkSpaceView.xaml"></Frame>
</ContentControl>
</TabItem>
<TabItem GotFocus="TabItem_Calfs_GotFocus">
<TabItem.Header>
Calfs
</TabItem.Header>
<ContentControl Margin="10">
<Frame Name="calfFrame" Source="CalfWorkSpaceView.xaml"></Frame>
</ContentControl>
</TabItem>
Refresh()是WorkSpaceViewControl类中的虚拟方法,并在后续类中被重写
每当我调用该代码时,它都会给我错误的选择。我尝试了很多强制转换方法:隐式、显式(正如您在上面的注释代码中看到的那样)
下面是我试图实现(但失败)的显式强制转换代码:
它总是将我的无效施法带入else条件:
我能投吗?怎么投?谢谢你的回答
更新
抽象类是:
public abstract class WorkSpaceViewControl : UserControl
{
public WorkSpaceViewControl()
{
InitializeComponent();
}
private void InitializeComponent()
{
//
}
#region Inheritance Methods (for sub classes
public virtual void GetSelectedEntry()
{
}
public virtual void Refresh()
{
}
public static explicit operator WorkSpaceViewControl(TabItem v)
{
if (v.Content is WorkSpaceViewControl)
{
return v.Content as WorkSpaceViewControl;
}
else
{
throw new InvalidCastException();
}
}
#endregion
}
试试这个
if (v.GetType().BaseType == typeof(WorkSpaceViewControl))
{
return v as WorkSpaceViewControl;
}
您有一个界面:
interface IWorkSpaceViewControl
{
void GetSelectedEntry();
void Refresh();
bool CanSave { get; }
void Save();
}
和一个用户控件:
<UserControl x:Class="WpfApplication9.DemoUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Button Name="btnChangeCanSave" Click="btnChangeCanSave_Click">Change CanSave</Button>
</Grid>
</UserControl>
和一个主窗口:
<Window xmlns:WpfApplication9="clr-namespace:WpfApplication9" x:Class="WpfApplication9.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">
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Save" CanExecute="SaveCommand_CanExecute" Executed="SaveCommand_Executed"/>
</Window.CommandBindings>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<WrapPanel>
<Button Name="btnRefresh" Click="btnRefresh_Click">Refresh</Button>
<Button Command="ApplicationCommands.Save">Save</Button>
</WrapPanel>
<TabControl Name="tabControl" Grid.Row="1">
<TabItem>
<TabItem.Header>Animals</TabItem.Header>
<WpfApplication9:DemoUserControl Margin="10" />
</TabItem>
</TabControl>
</Grid>
</Window>
老实说,我宁愿使用UserControls实现一个公共接口来实现您的目标,就像前面的问题一样。。。我不知道如何从帧中获取控件。。。谷歌搜索了一些,但找不到任何。。。无论如何,这会很混乱。。。从抽象类提取的公共接口,由当前从该类派生的UserControls实现,您就在那里。。。如果有共同的行为,我建议采用组合>继承的方法…我发布了一个包含多个接口的解决方案,但您也可以只使用一个包含所有共同成员的解决方案。。。将控件强制转换到接口并访问其成员,您就在那里…如果您发布抽象类,我们可以制定一个解决方案,实际上我希望以多态方式完成它(我不知道运行时的选项卡类型),因此继承毕竟是必须的。您也可以通过接口获得多态性。。。我来给你看看它会这样吗?我要试试看,然后再回来you@TalhaIrfan是的,您可以在执行Refresh()之前检查null,但这意味着该控件没有实现接口,因此您无法使用接口访问该控件。我的示例正确地将消息写入调试输出…@TalhaIrfan直接使用控件。。。没有框架可以直接使用控件。。。我将展开一个示例,在该示例中,当某个属性被禁用时,将命令绑定到禁用按钮的窗口false@TalhaIrfan更新。。。单击此演示控件中的按钮后,绑定到命令的按钮将被禁用。。。
<UserControl x:Class="WpfApplication9.DemoUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Button Name="btnChangeCanSave" Click="btnChangeCanSave_Click">Change CanSave</Button>
</Grid>
</UserControl>
public partial class DemoUserControl : UserControl, IWorkSpaceViewControl
{
private bool canSave;
public DemoUserControl()
{
InitializeComponent();
}
public void GetSelectedEntry()
{
// Your implementation
}
public void Refresh()
{
// Your Implementation
Debug.WriteLine("DemoUserControl Refresh() executed");
}
public bool CanSave
{
get { return canSave; }
}
private void btnChangeCanSave_Click(object sender, RoutedEventArgs e)
{
canSave = !canSave;
}
public void Save()
{
Debug.WriteLine("DemoUserControl Save() executed");
}
}
<Window xmlns:WpfApplication9="clr-namespace:WpfApplication9" x:Class="WpfApplication9.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">
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Save" CanExecute="SaveCommand_CanExecute" Executed="SaveCommand_Executed"/>
</Window.CommandBindings>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<WrapPanel>
<Button Name="btnRefresh" Click="btnRefresh_Click">Refresh</Button>
<Button Command="ApplicationCommands.Save">Save</Button>
</WrapPanel>
<TabControl Name="tabControl" Grid.Row="1">
<TabItem>
<TabItem.Header>Animals</TabItem.Header>
<WpfApplication9:DemoUserControl Margin="10" />
</TabItem>
</TabControl>
</Grid>
</Window>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void btnRefresh_Click(object sender, RoutedEventArgs e)
{
IWorkSpaceViewControl control = tabControl.SelectedContent as IWorkSpaceViewControl;
control.Refresh();
}
private void SaveCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (tabControl != null)
{
e.CanExecute = ((IWorkSpaceViewControl)tabControl.SelectedContent).CanSave;
}
}
private void SaveCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
((IWorkSpaceViewControl)tabControl.SelectedContent).Save();
}
}