【问题标题】:Open TabItem in a new Window在新窗口中打开 TabItem
【发布时间】:2019-02-11 05:38:30
【问题描述】:

在我的应用程序中,当加载 UserControlWindow 时,我有以下附加属性可以调用 ICommand

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

这很好用。在我看来,我将其称为UserControl,例如:

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

并且将调用视图模型中的ICommand

现在我实现了一项功能,我可以单击TabItem 标题中的Button 并在新窗口中打开此TabItem 的内容。 (就像在 Visual Studio 中取消停靠选项卡一样)。

因此我使用以下代码:

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

这也很好用。

我现在的问题是,如果我打开一个新选项卡(witch 还包含一个 TabControl,其中 TabItems 具有加载的附加属性)并使用上面的代码将此选项卡移动到新窗口:加载命令当我切换到使用加载附加属性的视图时不会调用。

如果我调试附加属性,我可以看到,正确调用了 OnLoadedCommandChanged,但未调用 UserControlOnLoaded。如果我没有在新窗口中打开TabItem,则会正确调用 UserControlOnLoaded。

如果我将TabItem 移动到新的Window,子页面的加载事件不会被触发的任何想法?

【问题讨论】:

  • DataContext 看不到任何东西,但你确定它没有被新窗口改变吗?
  • 是的,我确定。我觉得我发现了问题。 WorkspaceTab.Items.Remove(workspaceTab); 行从选项卡控件中删除选项卡。我似乎删除也清理了所有事件

标签: c# wpf attached-properties


【解决方案1】:

问题出在WorkspaceTab.Items.Remove(workspaceTab);这一行内

这一行从TabControl 中删除了TabItem,看来wpf 在这里做了某种清理。

我已经解决了这个问题,只需将TabItemVisibility 设置为隐藏。

【讨论】:

    猜你喜欢
    • 2015-02-28
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-04
    • 2014-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多