Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在WPF中将TabItem强制转换为UserControl_C#_Wpf_Casting_Tabs_User Controls - Fatal编程技术网

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();
    }
}