简体   繁体   中英

Open TabItem in a new Window

In my application I have the following attached-property to call an ICommand when a UserControl or Window is loaded:

public static readonly DependencyProperty LoadedCommandProperty = DependencyProperty.RegisterAttached(
    "LoadedCommand", typeof(ICommand), typeof(UserControlExtensions), new PropertyMetadata(null, OnLoadedCommandChanged));

private static void OnLoadedCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    ContentControl userControl = d as ContentControl;
    if (userControl == null)
        return;

    if (e.NewValue is ICommand)
    {
        userControl.Loaded += UserControlOnLoaded;
    }
}

private static void UserControlOnLoaded(object sender, RoutedEventArgs e)
{
    ContentControl userControl = sender as ContentControl;
    if (userControl == null)
        return;

    ICommand command = GetLoadedCommand(userControl);
    command.Execute(GetLoadedCommandParameter(userControl));
}

public static void SetLoadedCommand(DependencyObject element, ICommand value)
{
    element.SetValue(LoadedCommandProperty, value);
}

public static ICommand GetLoadedCommand(DependencyObject element)
{
    return (ICommand) element.GetValue(LoadedCommandProperty);
}

public static readonly DependencyProperty LoadedCommandParameterProperty = DependencyProperty.RegisterAttached(
    "LoadedCommandParameter", typeof(object), typeof(UserControlExtensions), new PropertyMetadata(default(object)));

public static void SetLoadedCommandParameter(DependencyObject element, object value)
{
    element.SetValue(LoadedCommandParameterProperty, value);
}

public static object GetLoadedCommandParameter(DependencyObject element)
{
    return (object) element.GetValue(LoadedCommandParameterProperty);
}

This just works fine. In my views I call this on a UserControl like:

AttachedProperties:UserControlExtensions.LoadedCommand="{Binding ViewLoadedCommand}"

And the ICommand in the viewmodel will be called.

Now I've implemented a feature that I can click on a Button in the header of a TabItem and open the content of this TabItem in a new Window. (Like undocking a Tab in the visual studio).

Therefor I'm using the following code:

private void OpenInWindowButtonOnClick(object sender, RoutedEventArgs e)
{
    Button button = sender as Button;
    if (button == null)
        return;

    TabItem tabItem = button.Tag as TabItem;
    if (tabItem == null)
        return;

    string title = string.Empty;

    ContentControl headerContent = tabItem.Header as ContentControl;
    if (headerContent != null)
    {
        title = headerContent.Content.ToString();
    }

    string workspaceId = tabItem.Tag as string;

    TabItem workspaceTab = WorkspaceTab.Items.OfType<TabItem>()
        .FirstOrDefault(ti => ti.Tag is string && (string)ti.Tag == workspaceId);
    if (workspaceTab != null)
    {
        WorkspaceWindow workspaceWindow = new WorkspaceWindow(tabItem);
        workspaceWindow.Content = workspaceTab.Content;

        workspaceWindow.Width = (workspaceTab.Content as FrameworkElement).ActualWidth;
        workspaceWindow.Height = (workspaceTab.Content as FrameworkElement).ActualHeight;

        workspaceWindow.Title = title;
        workspaceWindow.Closing += WorkspaceWindowOnClosing;
        workspaceWindow.Show();
        workspaceWindows.Add(workspaceId, workspaceWindow);
        WorkspaceTab.Items.Remove(workspaceTab);
    }
}

This also just works fine.

My problem now is if I open a new tab (witch contains also a TabControl where the TabItem s have the loaded-attachedproperty) and move this tab to a new window with the code above: The loaded-command will not called when I switch to the view where the loaded-attachedproperty is used.

If I debug the attachedproperty I can see, that the OnLoadedCommandChanged is called correctly but the UserControlOnLoaded is not called. If I don't open the TabItem in a new Window the UserControlOnLoaded is called correctly.

Any ideas why the loaded-event of subpages don't get fired if I move a TabItem to a new Window ?

The problem was within the line WorkspaceTab.Items.Remove(workspaceTab);

This line removes the TabItem from the TabControl and it seems that wpf does here some kind of cleanup.

I've solved the problem be just setting the Visibility of the TabItem to Hidden.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM