从外部视图模型访问选项卡数据

时间:2018-09-15 21:07:22

标签: c# wpf xaml mvvm tabcontrol

基本上我的应用程序看起来像这样,我使用的是mvvm模式,但我仍然是新手。用户可以在每个标签内动态添加标签,如图所示。每个选项卡中都有文本框和复选框。

enter image description here

基本结构是我具有PriceViewModel.cs,PriceTab.xaml(用户控件)和MainWindow.xaml。

在PriceViewModel.cs

public class PriceViewModel : PriceTabItem
{

    private string _PriceLevel;
    private bool _Buy;
    private bool _Sell;
    public string PriceLevel
    {
        get { return _PriceLevel; }
        set
        {
            _PriceLevel = value;
            OnPropertyChanged("PriceLevel");
        }
    }
    public bool Buy
    {
        get { return _Buy; }
        set
        {
            _Buy = value;
            OnPropertyChanged("Buy");
        }
    }
    public bool Sell
    {
        get { return _Sell; }
        set
        {
            _Sell = value;
            OnPropertyChanged("Sell");
        }
    }
    public PriceViewModel()
    {

    }

}

public abstract class PriceTabItem : PropertyChangedBase
{
    public string Title { get; set; }
    public string Header { get; set; }
    public string Content { get; set; }
}

public class PriceTabControl : PropertyChangedBase
{
    public ObservableCollection<PriceTabItem> Tabs { get; set; }
    private PriceTabItem _selectedTab;
    public PriceTabItem SelectedTab
    {
        get { return _selectedTab; }
        set
        {
            _selectedTab = value;
            OnPropertyChanged("SelectedTab");
        }
    }

    public Command AddNewTabCommand { get; set; }

    public PriceTabControl()
    {

        Tabs = new ObservableCollection<PriceTabItem>();
        AddNewTabCommand = new Command(AddNewTab);
    }
    private void AddNewTab()
    {
        var newtab = new PriceViewModel { Title = "Tab #" + (Tabs.Count + 1) };
        Tabs.Add(newtab);
        SelectedTab = newtab;
    }
}

在PriceTab.xaml中:

    <UserControl x:Class="MyApp.PriceTab"
         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" 
         xmlns:local="clr-namespace:MyApp.ViewModels"
         mc:Ignorable="d" 
        d:DesignHeight="300" d:DesignWidth="700">
<UserControl.Resources>
<DataTemplate DataType="{x:Type local:PriceViewModel}">

<Grid>
    <TextBox HorizontalAlignment="Left" Height="19" Text="{Binding PriceLevel}" Margin="101,155,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="81" RenderTransformOrigin="-0.177,0.286"/>
    <CheckBox Content="Buy" IsChecked="{Binding Buy}" HorizontalAlignment="Left" Height="20" Margin="16,109,0,0" VerticalAlignment="Top" Width="73"/>
    <CheckBox Content="Sell" IsChecked="{Binding Sell}" HorizontalAlignment="Left" Height="20" Margin="122,109,0,0" VerticalAlignment="Top" Width="73"/>

</Grid>

</DataTemplate>
</UserControl.Resources>
<DockPanel>

    <Button Command="{Binding AddNewTabCommand}" Content="AddNewTab"
            DockPanel.Dock="Bottom"/>

    <TabControl ItemsSource="{Binding Tabs}"
                SelectedItem="{Binding SelectedTab}"
                DisplayMemberPath="Title">
    </TabControl>
</DockPanel></UserControl>

在PriceTab.xaml.cs中:

public partial class HistogramPriceTab : UserControl
{
    public HistogramPriceTab()
    {
        InitializeComponent();
        DataContext = new PriceTabControl();
    }
}

在MainWindow.xaml中:

<Window x:Class="MyApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:MyApp"
    mc:Ignorable="d"
    Title="MainWindow" Height="550" Width="850">

    <Grid Width="Auto" Height="Auto">
        <Button Name="SaveButton" Content="Save" HorizontalAlignment="Left" Height="33.16" Margin="701.5,11,0,0" VerticalAlignment="Top" Width="88.5" Click="SaveButton_Click"/>

        <TabControl HorizontalAlignment="Left" Height="485" Margin="-7,28,0,-7.6" VerticalAlignment="Top" Width="850" >
            <TabItem>
                <local:OtherTabs></local:OtherTabs>
            </TabItem>
            <TabItem Name="Price" Header="Price">
                <Grid Background="#FFE5E5E5">
                    <local:PriceTab></local:PriceTab>
                </Grid>
            </TabItem>
            <TabItem>
                <Grid Background="#FFE5E5E5">
                    <local:OtherTabs></local:OtherTabs>
                </Grid>
            </TabItem>
            <TabItem>
                <Grid Background="#FFE5E5E5">
                    <local:OtherTabs></local:OtherTabs>
                </Grid>
            </TabItem>
            <TabItem>
                <Grid Background="#FFE5E5E5">
                    <local:OtherTabs></local:OtherTabs>
                </Grid>
            </TabItem>
            <TabItem>
                <Grid Background="#FFE5E5E5">
                    <local:OtherTabs></local:OtherTabs>
                </Grid>
            </TabItem>
            <TabItem>
                <Grid Background="#FFE5E5E5">
                   <local:OtherTabs></local:OtherTabs>
                </Grid>
            </TabItem>
            <TabItem>
                <Grid Background="#FFE5E5E5">
                    <local:OtherTabs></local:OtherTabs>
                </Grid>
            </TabItem>

        </TabControl>
    </Grid></Window>

因此,在右上角,我有一个“保存”按钮,当单击该按钮时,它将必须从选项卡中获取所有输入,并根据它们进行一些计算和制图,并显示在下一个窗口中。因此,基本上,我希望下一个窗口能够引用此窗口中的所有输入。如何使用模式来解决这个问题? 预先感谢!

2 个答案:

答案 0 :(得分:0)

硬写xaml不允许您动态创建标签。

您应该考虑通过在ItemViewView的选项卡视图模型列表上使用带有ItemSouce绑定的ItemControl来创建选项卡。看看this tutorial about itemcontrol

这样,当您想做一些需要所有选项卡信息的业务时,可以通过tabsviewmodels列表访问它们

答案 1 :(得分:0)

之后找到了它,因此要引用这些标签和其中的所有项目, 看到下面的代码,我们可以使用访问孩子的xaml文件访问“价格水平”(例如)文本框。

 var pricetabs = (((this.Price.Content as Grid).Children[0] as PriceTab).DataContext as ViewModels.PriceTabControl).Tabs;
 String res = "";
 foreach (ViewModels.PriceViewModel v in pricetabs)
 {
     res += v.PriceLevel.ToString()
 }

老实说,不确定这是否是正确的方法,或者不确定它是否破坏了mvvm结构,但确实可以做到!