在WPF中将TabItem转换为UserControl

时间:2015-03-11 02:44:23

标签: c# wpf casting tabs user-controls

我的主屏幕上有一个Tab Control。它有不同的标签项。例如:

<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>

等......

以下是标签的设计时预览:

Tab Controls overview

每个标签项控件都继承自 WorkSpaceViewControl (从 UserControl 派生的抽象类)

正如您所看到的,有一个刷新按钮来刷新控件(重新加载它的 datagrid 成员)

刷新按钮后面的代码是:

private void buttonRefresh_Click(object sender, RoutedEventArgs e)
        {
        //var x = mainTab.SelectedItem as TabItem;
        //MessageBox.Show(x.Header.ToString());//shows the header
        //var t = x.Content as TextBlock;
        //MessageBox.Show(t.Text);

        var ctrl = mainTab.SelectedItem as TabItem;

        var myCtrl1 = (WorkSpaceViewControl)ctrl;
        myCtrl1.Refresh();
}

Refresh()是 WorkSpaceViewControl 类中的虚方法,并在后续类中重写。

每当我调用该代码时,它会让我在投射时出错。我尝试了很多种方法:隐式,显式(,因为你可以看到上面注释代码中的一些尝试)。

这是我试图实现的显式转换代码(但失败了):

public static explicit operator WorkSpaceViewControl(TabItem v)
        {
            if (v.Content is WorkSpaceViewControl)
            {
                return v.Content as WorkSpaceViewControl;
            }
            else
            {
                throw new InvalidCastException();
            }
        }

它总是通过进入其他条件而抛出Invalid Cast:

Invalid Cast

我可以施展它吗?谢谢你回答。

更新

抽象类是:

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
}

2 个答案:

答案 0 :(得分:4)

你有一个界面:

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>

代码背后:

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

和MainWindow:

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

答案 1 :(得分:-2)

试试这个

if (v.GetType().BaseType == typeof(WorkSpaceViewControl))
{
    return v as WorkSpaceViewControl;
}