Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在使用点将数据网格分配给WPF中的用户控件?_C#_Wpf_Data Binding_Datagrid_User Controls - Fatal编程技术网

C# 如何在使用点将数据网格分配给WPF中的用户控件?

C# 如何在使用点将数据网格分配给WPF中的用户控件?,c#,wpf,data-binding,datagrid,user-controls,C#,Wpf,Data Binding,Datagrid,User Controls,我试图为典型的双列表情况定义一个用户控件(其中有两个并排的项目列表和按钮控件,用于将所选项目从一个转移到另一个)。我对WPF不是很精通——我所学到的大部分知识都是通过类似这样的网站获得的。我已经了解到,我可以为控件创建自定义依赖属性,这样我就可以推迟控件中项目(按钮、文本框等)的绑定,直到控件实际使用为止,这非常好。然而,对于我的控制,我将有两个列表(可能是DataGrids,因为我的大部分代码都涉及到它们),但它们需要的不仅仅是绑定,所以我想做的是这样的: <MyUserCont

我试图为典型的双列表情况定义一个用户控件(其中有两个并排的项目列表和按钮控件,用于将所选项目从一个转移到另一个)。我对WPF不是很精通——我所学到的大部分知识都是通过类似这样的网站获得的。我已经了解到,我可以为控件创建自定义依赖属性,这样我就可以推迟控件中项目(按钮、文本框等)的绑定,直到控件实际使用为止,这非常好。然而,对于我的控制,我将有两个列表(可能是DataGrids,因为我的大部分代码都涉及到它们),但它们需要的不仅仅是绑定,所以我想做的是这样的:

    <MyUserControl . . . .>
        <DataGrid . . . .>
        <DataGrid . . . .>
    </MyUserControl>

但我不知道该怎么做。我认为可能有某种方法可以使用ContentControls作为数据网格的替代,然后以某种方式将数据网格链接回usercontrol中的ContentControls,但我并不真正理解ContentControls,而且我发现使用它们的示例似乎都不适用于我想要做的事情


有人能给我指出正确的方向吗?谢谢。

我做了更多的研究,发现了一种很有希望的方法,如下所示:

我做了一个小的概念验证项目,效果很好,所以我想在这里分享一下。它使用Galasoft的MVVM轻型框架

我创建了一个带有textblock、ContentControl和按钮的用户控件:

    <UserControl x:Class="DataGridInUserControlDemo.UserControls.DGPlusUC"
            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:ignore="http://www.galasoft.ch/ignore"
            mc:Ignorable="d ignore"
            x:Name="ControlRoot">
        <Grid DataContext="{Binding ElementName=ControlRoot}" Margin="10, 10, 10, 10" MinHeight="300" MinWidth="300">
            <Grid.RowDefinitions>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="5*"/>
                <RowDefinition Height="2*"/>
            </Grid.RowDefinitions>
            <TextBlock Grid.Row="0" Text="{Binding Path=BannerText}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20"/>
            <ContentControl Grid.Row="1" Content="{Binding Path=InnerContent}" />
            <Button Grid.Row="2" x:Name="DemoButton" Content="{Binding Path=ButtonContent}" Command="{Binding Path=ButtonCommand}" Width="75" Height="25" HorizontalAlignment="Center" VerticalAlignment="Center" />
        </Grid>
    </UserControl>
这是主窗口的XAML:

    <Window x:Class="DataGridInUserControlDemo.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:ignore="http://www.galasoft.ch/ignore"
            xmlns:demo="clr-namespace:DataGridInUserControlDemo.UserControls"
            mc:Ignorable="d ignore"
            Height="400"
            Width="400"
            Title="MVVM Light Application"
            DataContext="{Binding Main, Source={StaticResource Locator}}">

        <Window.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="Skins/MainSkin.xaml" />
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </Window.Resources>
        <Grid x:Name="LayoutRoot">
            <demo:DGPlusUC BannerText="{Binding UCTitle}"  ButtonContent="{Binding ButtonText}" ButtonCommand="{Binding ButtonCommand}" HorizontalAlignment="Center" VerticalAlignment="Center">
                <demo:DGPlusUC.InnerContent>
                    <Grid DataContext="{Binding Main, Source={StaticResource Locator}}">
                        <DataGrid ItemsSource="{Binding Path=DataItems}" AutoGenerateColumns="True" />
                    </Grid>
                </demo:DGPlusUC.InnerContent>
            </demo:DGPlusUC>
        </Grid>
    </Window>
最后,以下是结果:


您的代码可能并不“需要比绑定多得多”-如果您的数据绑定到viewmodel,那么该模型可以实现您所需的任何级别的复杂性,并通过绑定将状态更改反映回UI。感谢您的评论,但我如何处理列数和大小、标题、,视图模型中的列格式等?我知道我可以自动生成列,但这并不能让我对它们有太多的控制,而且这些关注点大多与视图相关,因此它们似乎不太可能在视图模型中完成。你的观点很好,我真的无法判断你的问题,但对我来说,viewmodel应该负责列的数量是有道理的。通过绑定实现它。我同意格式是视图真正关心的问题,因此我将在xaml中定义所有列,但让viewmodel控制它们的可见性。
    <Window x:Class="DataGridInUserControlDemo.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:ignore="http://www.galasoft.ch/ignore"
            xmlns:demo="clr-namespace:DataGridInUserControlDemo.UserControls"
            mc:Ignorable="d ignore"
            Height="400"
            Width="400"
            Title="MVVM Light Application"
            DataContext="{Binding Main, Source={StaticResource Locator}}">

        <Window.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="Skins/MainSkin.xaml" />
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </Window.Resources>
        <Grid x:Name="LayoutRoot">
            <demo:DGPlusUC BannerText="{Binding UCTitle}"  ButtonContent="{Binding ButtonText}" ButtonCommand="{Binding ButtonCommand}" HorizontalAlignment="Center" VerticalAlignment="Center">
                <demo:DGPlusUC.InnerContent>
                    <Grid DataContext="{Binding Main, Source={StaticResource Locator}}">
                        <DataGrid ItemsSource="{Binding Path=DataItems}" AutoGenerateColumns="True" />
                    </Grid>
                </demo:DGPlusUC.InnerContent>
            </demo:DGPlusUC>
        </Grid>
    </Window>
    using GalaSoft.MvvmLight;
    using GalaSoft.MvvmLight.CommandWpf;
    using DataGridInUserControlDemo.Model;
    using System.Windows.Input;
    using System.Collections.ObjectModel;

    namespace DataGridInUserControlDemo.ViewModel
    {
        public class MainViewModel : ViewModelBase
        {
            private readonly IDataModel theModel;

            private ObservableCollection<DataItem> _DataItems;

            public ObservableCollection<DataItem> DataItems
            {
                get
                {
                    return _DataItems;
                }

                set
                {
                    if (_DataItems == value)
                    {
                        return;
                    }

                    var oldValue = _DataItems;
                    _DataItems = value;
                    RaisePropertyChanged(() => DataItems, oldValue, value, true);
                }
            }


            private string _ButtonText = "First";
            public string ButtonText
            {
                get
                {
                    return this._ButtonText;
                }

                set
                {
                    if (this._ButtonText == value)
                    {
                        return;
                    }

                    var oldValue = this._ButtonText;
                    this._ButtonText = value;
                    RaisePropertyChanged(() => ButtonText, oldValue, value, true);
                }
            }


            private string _UCTitle = string.Empty;
            public string UCTitle
            {
                get
                {
                    return this._UCTitle;
                }

                set
                {
                    if (this._UCTitle == value)
                    {
                        return;
                    }

                    var oldValue = this._UCTitle;
                    this._UCTitle = value;
                    RaisePropertyChanged(() => UCTitle, oldValue, value, true);
                }
            }

            private ICommand _ButtonCommand;
            public ICommand ButtonCommand
            {
                get
                {
                    return this._ButtonCommand;
                }

                set
                {
                    if (this._ButtonCommand == value)
                    {
                        return;
                    }

                    var oldValue = this._ButtonCommand;
                    this._ButtonCommand = value;
                    RaisePropertyChanged(() => ButtonCommand, oldValue, value, true);
                }
            }

            public MainViewModel(IDataModel model)
            {
                this.theModel = model;
                this._UCTitle = "DataGrid in User Control Demo";
                this._DataItems = new ObservableCollection<DataItem>(this.theModel.SomeData);
                this._ButtonCommand = new RelayCommand(this.ButtonCmd, () => { return true; }) ;
            }

            private void ButtonCmd()
            {
                if (this.ButtonText == "First")
                {
                    this.ButtonText = "Second";
                }
                else
                {
                    this.ButtonText = "First";
                }
            }
        }
    }