首页 文章

在WPF MVVM中动态创建TabControl和子网格

提问于
浏览
0

我有一个使用Devexpress作为第三方工具的wpf mvvm应用程序 . 我需要动态创建包含datagrids的选项卡 . 我想知道这样做的最佳做法是什么 . 我已经创建了一个View包含一个tab和contenttemplate

<TabControl ItemsSource="{Binding Workspaces}">
        <TabControl.ContentTemplate>
            <DataTemplate>
                <DataGrid ItemsSource="{Binding Data}" AutoGenerateColumns="False">
                    <DataGrid.Columns >
                        <DataGridTextColumn Header="Column 1" Binding="{Binding Column1}" />
                        <DataGridTextColumn Header="Column 2" Binding="{Binding Column2}" />
                        <DataGridTextColumn Header="Column 3" Binding="{Binding Column3}" />
                    </DataGrid.Columns>
                </DataGrid>
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>

我的观点模型

public class DataTest
{
    public string Column1 { get; set; }
    public string Column2 { get; set; }
    public string Column3 { get; set; }
}


public abstract class WorkspaceViewModel 
{
    public String HeaderText { get; set; }
    public override string ToString()
    {
        return HeaderText;
    }
    //ObservableCollection
    public ObservableCollection<DataTest> Data { get; set; }

}


public class FirstUserControlViewModel : WorkspaceViewModel
{
    public FirstUserControlViewModel()
    {
        base.HeaderText = "My First Tab";
        Data = new ObservableCollection<DataTest>();
        for (int i = 0; i < 5; i++)
        {
            Data.Add(new DataTest()
                        {
                            Column1 = "1st Test" + i.ToString(),
                            Column2 = "1st Test" + i.ToString(),
                            Column3 = "1st Test" + i.ToString()
                        }); 
        }
    }
}


public class SecondUserControlViewModel : WorkspaceViewModel
{
    public SecondUserControlViewModel()
    {
        base.HeaderText = "My Second Tab";
        Data = new ObservableCollection<DataTest>();
        for (int i = 0; i < 5; i++)
        {
            Data.Add(new DataTest()
            {
                Column1 = "2nd Test" + i.ToString(),
                Column2 = "2nd Test" + i.ToString(),
                Column3 = "2nd Test" + i.ToString()
            });
        }
    }
}

public class ThirdUserControlViewModel : WorkspaceViewModel
{
    public ThirdUserControlViewModel()
    {
        base.HeaderText = "My Third Tab";
        Data = new ObservableCollection<DataTest>();
        for (int i = 0; i < 5; i++)
        {
            Data.Add(new DataTest()
            {
                Column1 = "3rd Test" + i.ToString(),
                Column2 = "3rd Test" + i.ToString(),
                Column3 = "3rd Test" + i.ToString()
            });
        }
    }
}

public class ViewModel
{

    private ObservableCollection<WorkspaceViewModel> _workspaces;

    public ObservableCollection<WorkspaceViewModel> Workspaces
    {
        get
        {
            if (_workspaces == null)
            {
                _workspaces = new ObservableCollection<WorkspaceViewModel>();
            }
            return _workspaces;
        }
    }


    public ViewModel()
    {
        Workspaces.Add(new FirstUserControlViewModel());
        Workspaces.Add(new SecondUserControlViewModel());
        Workspaces.Add(new ThirdUserControlViewModel());
    }

}

这已经有效,但我想知道是否有更好的方法 . 我应该将datagrid放在usercontrol中并传递其参数Data . 我也在这个应用程序中使用Prism是否有可以利用的东西有益处?

1 回答

  • 0

    这将起作用,但前提是所有选项卡都要显示完全相同的控件,并且网格显示完全相同的数据结构 .

    如果你想要替代控件或数据,我建议使用隐式 DataTemplates 而不是硬编码 ContentTemplate

    <TabControl ItemsSource="{Binding Workspaces}">
        <TabControl.Resources>
            <!-- Draw WorkspaceAViewModel with WorkspaceAView -->
            <DataTemplate TargetType="{x:Type local:WorkspaceAViewModel}">
                <local:WorkspaceAView />
            </DataTemplate>
    
            <!-- Draw WorkspaceBViewModel with WorkspaceBView -->
            <DataTemplate TargetType="{x:Type local:WorkspaceBViewModel}">
                <local:WorkspaceBView />
            </DataTemplate>
    
            <!-- Draw WorkspaceCViewModel with WorkspaceCView -->
            <DataTemplate TargetType="{x:Type local:WorkspaceCViewModel}">
                <local:WorkspaceCView />
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>
    

    这样,您可以将每个工作空间设置为任何对象模型(可能具有共享接口,因此存在将 Headers 文本绑定到的公共属性),并且可以以任何方式绘制每个选项卡 .

    public class ViewModel
    {
        private ObservableCollection<WorkspaceViewModel> _workspaces;
        public ObservableCollection<WorkspaceViewModel> Workspaces
        {
            get
            {
                if (_workspaces == null)
                    _workspaces = new ObservableCollection<WorkspaceViewModel>();
    
                return _workspaces;
            }
        }
    
        public ViewModel()
        {
            Workspaces.Add(new WorkspaceAViewModel ());
            Workspaces.Add(new WorkspaceBViewModel ());
            Workspaces.Add(new WorkspaceCViewModel ());
        }
    }
    
    public interface IWorkspace
    {
        string Header { get; set; }
    }
    
    public class WorkspaceAViewModel : IWorkspace
    {
        // can be anything
    }
    
    public class WorkspaceBViewModel : IWorkspace
    {
        // can be anything
    }
    
    public class WorkspaceCViewModel : IWorkspace
    {
        // can be anything
    }
    

相关问题