简体   繁体   English

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

[英]access tab data from outside view model

Basically my application looks like this, i'm using mvvm pattern but i'm still new to it. 基本上我的应用程序看起来像这样,我使用的是mvvm模式,但我仍然是新手。 Within each tab, user can dynamically add tabs as shown in the picture. 用户可以在每个标签内动态添加标签,如图所示。 Within each tabs, there are text boxes and check boxes. 在每个选项卡中,都有文本框和复选框。

在此处输入图片说明

The basic structure is I have PriceViewModel.cs, PriceTab.xaml (usercontrol), and MainWindow.xaml. 基本结构是我具有PriceViewModel.cs,PriceTab.xaml(用户控件)和MainWindow.xaml。

In PriceViewModel.cs 在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;
    }
}

In PriceTab.xaml: 在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>

In PriceTab.xaml.cs: 在PriceTab.xaml.cs中:

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

In MainWindow.xaml: 在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>

So on the top right corner I have a "save" button, when clicked, it will have to get all the inputs from the tabs and do some calculation and charting based on them and show on to the next window. 因此,在右上角,我有一个“保存”按钮,当单击该按钮时,它将必须从选项卡中获取所有输入,并根据它们进行一些计算和制图,然后显示在下一个窗口中。 So basically I want the next window to be able to reference all inputs from this window. 因此,基本上,我希望下一个窗口能够引用此窗口中的所有输入。 How do I approach this with the pattern ? 如何使用模式来解决这个问题? Thanks in advance! 提前致谢!

Hard writting the xaml don't allow you to create your tabs dynamically. 硬性地写Xaml不允许您动态创建选项卡。

You should consider creating your tabs by using an ItemControl with its itemSouce bind on a list of your tabs viewmodels in your priceviewmodel. 您应该考虑通过在priceviewmodel的选项卡视图模型列表中使用带有ItemSouce绑定的ItemControl来创建选项卡。 Take a look at this tutorial about itemcontrol 看一下有关itemcontrol的本教程

This way when you want to do some business that requires information about all the tabs you can access to them through the list of tabsviewmodels 这样,当您想做一些需要所有选项卡信息的业务时,可以通过选项卡视图模型列表访问它们

Figured it out afterwards, so to reference the tabs and all the items inside, see the below code we can have access to the Price Level (as example) textbox using the xaml file accessing the children. 之后将其弄清楚,因此要引用选项卡和其中的所有项目,请参见下面的代码,我们可以使用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()
 }

Honestly not sure this is the proper way to do it or if it defeats the mvvm structure, but it does the job! 老实说,不确定这是执行此操作的正确方法,还是不确定它是否破坏了mvvm结构,但确实可以完成工作!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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