从子UserControl更改父Window TabControl的选项卡

时间:2017-10-16 00:55:04

标签: c# wpf xaml mvvm user-controls

我有一个父窗口,里面有TabControl。每个标签都包含与其关联的UserControl。在我的一个UserControl中,我有一个按钮。单击按钮时,我想更改父窗口中TabControl的选定选项卡。

我使用MVVM模式,所以如果可能的话,我想在我的按钮上使用Command属性在XAML中进行。

例如:

<Button Content="Switch Tab" Command="{Binding SwitchTabCommand}" />

先谢谢我的同事们!

父窗口视图模型:

public class CoolViewModel : BaseViewModel
{
    #region Properties

    public ObservableCollection<ITabViewModel> Tabs { get; set; }
    public ITabViewModel SelectedTab { get; set; }

    #endregion

    #region Constructor

    public CoolViewModel()
    {
        Tabs = new ObservableCollection<ITabViewModel>
        {
            new VeryNiceViewModel(),
            new VeryNiceViewModel()
        };
    }

    #endregion
}

以下是选项卡中UserControl的代码:

public class VeryCoolViewModel : BaseViewModel, ITabViewModel
{
    #region Properties

    public ObservableCollection<Test> Tests { get; set; }
    public Test currentSelection { get; set; }
    public string TabHeader { get; set; }

    #endregion

    #region Commands

    ICommand GoToOtherTab { get; set; }

    #endregion

    #region Constructor

    public GabaritSelecteurViewModel()
    {
        Tests = new ObservableCollection<Test>
        {
            new Test { Title = "Title #1" },
            new Test { Title = "Title #2" },
            new Test { Title = "Title #3" },
            new Test { Title = "Title #4" },
            new Test { Title = "Title #5" }
        };

        TabHeader = "Tests";

        GoToOtherTab = new RelayCommand(GoToTab, parameter => true);
    }

    #endregion

    #region Methods

    private void GoToTab(object parameter)
    {
        // I don't know how to tell to the
        // parent window to go to the other tab...
    }

    #endregion
}

这里是UserControl的XAML(位于TabControl中):

<Button Content="Go to the other tab" Command="{Binding GoToOtherTab}" />

2 个答案:

答案 0 :(得分:0)

您可以尝试添加到VeryCoolViewModel(您的UserControl VM)事件:

public class VeryCoolViewModel : BaseViewModel, ITabViewModel
{
    #region Properties

    public ObservableCollection<Test> Tests { get; set; }
    public Test currentSelection { get; set; }
    public string TabHeader { get; set; }

    public delegate void ChangeSelectedTab(string tabName)
    public event ChangeSelectedTab OnChangeSelectedTab
    #endregion

    #region Commands

    ICommand GoToOtherTab { get; set; }

    #endregion

    #region Constructor

    public GabaritSelecteurViewModel()
    {
        Tests = new ObservableCollection<Test>
        {
            new Test { Title = "Title #1" },
            new Test { Title = "Title #2" },
            new Test { Title = "Title #3" },
            new Test { Title = "Title #4" },
            new Test { Title = "Title #5" }
        };

        TabHeader = "Tests";

        GoToOtherTab = new RelayCommand(GoToTab, parameter => true);
    }

    private void GoToTab(object parameter)
    {
            OnChangeSelectedTab?.Invoke((string)parameter);
    }
}

并在constuctor中进入父窗口VM:

public CoolViewModel()
{
    Tabs = new ObservableCollection<ITabViewModel>
    {
         new VeryNiceViewModel(),
         new VeryNiceViewModel()
    };
    Tabs.ForEach(x =>{
        x.OnChangeSelectedTab += x_OnChangeSelectedTab
    });

}

private void x_OnChangeSelectedTab(string tabName)
{
     // select from List of tabItems tabItem with name == tabName and then set propetry in this tabItem to true.
     SomePropertyInParentViewModel = true;
}

在视图中:

<TabItem x:Name="TabWhatYouNeed" IsSelected="{Binding SomePropertyInParentViewModel}">

答案 1 :(得分:0)

你可以做一些有点“hacky”的事情但很简单。如果你的每个UserControl都没有自己的ViewModel(不太确定为什么需要它),那就不那么容易了。

无论如何,我们的目标是到达private void AddFooterData(Section section) { var rightFooterSection = new Paragraph { Format = { Alignment = ParagraphAlignment.Right } }; rightFooterSection.AddText("Prepared By Eng: " + _preparedBy); var rightFooterPagePar = new Paragraph { Format = { Alignment = ParagraphAlignment.Right } }; rightFooterPagePar.AddText("Page "); rightFooterPagePar.AddPageField(); rightFooterPagePar.AddText("/"); rightFooterPagePar.AddNumPagesField(); var date = DateTime.Now.ToString("yyyy/MM/dd"); var leftSection = new Paragraph { Format = { Alignment = ParagraphAlignment.Left } }; var leftDateSection = new Paragraph { Format = { Alignment = ParagraphAlignment.Left } }; leftSection.AddText("Approved By: " + _approvedBy); leftDateSection.AddText(date); var footerTable = section.Footers.Primary.AddTable(); var col1 = footerTable.AddColumn(); col1.Width = "5.5in"; var col2 = footerTable.AddColumn(); col2.Width = "5.5in"; var row1 = footerTable.AddRow(); row1[0].Add(leftSection); row1[1].Add(rightFooterSection); row1.Borders.Bottom.Visible = true; row1.Borders.Bottom.Width = "0.10cm"; var row2 = footerTable.AddRow(); row2[0].Add(leftDateSection); row2[1].Add(rightFooterPagePar); 。我们怎么去那里? CoolViewModel。简而言之,它允许您绑定到不同的范围(除了您自己的RelativeSource Binding之外,在此示例中是UserControl。)

所以,我们知道你有一个DataContext来保存所有这些UserControl,我们知道这个TabControl的TabControlDataContext

  1. CoolViewModel放在Command中,如下所示:

    CoolViewModel  

  2. 使用UserControl绑定到它:

    public ICommand SwitchTabCommand {get;set;}

  3. 所以基本上你正在寻找最近的祖先<Button Content="Go to the other tab" Command= "{Binding RelativeSource={RelativeSource AncestorType={x:Type TabControl}}, Path=DataContext.SwitchTabCommand}" />,通过TabControl查看命令DataContext