Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.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# 更新datagrid中的动态列_C#_Wpf_Data Binding_Datagrid_Combobox - Fatal编程技术网

C# 更新datagrid中的动态列

C# 更新datagrid中的动态列,c#,wpf,data-binding,datagrid,combobox,C#,Wpf,Data Binding,Datagrid,Combobox,我整天都在做这个,但是我被卡住了,没有解决办法。这似乎很简单 我有一个具有动态列数的datagrid。每列都有一个DataGridTemplateColumn,其中包含一个CellTemplate和一个CellEditingTemplate。CellEditingTemplate包含一个带有值的组合框,用户选择值后,CellTemplate中的文本框必须更新为所选值。通常情况下,您会将其绑定到对象中的已知属性,但由于我不知道用户事先需要多少列,因此我必须在运行时创建这些属性(或其他内容),并尝试

我整天都在做这个,但是我被卡住了,没有解决办法。这似乎很简单

我有一个具有动态列数的datagrid。每列都有一个DataGridTemplateColumn,其中包含一个CellTemplate和一个CellEditingTemplate。CellEditingTemplate包含一个带有值的组合框,用户选择值后,CellTemplate中的文本框必须更新为所选值。通常情况下,您会将其绑定到对象中的已知属性,但由于我不知道用户事先需要多少列,因此我必须在运行时创建这些属性(或其他内容),并尝试将此textbox和combobox绑定到此属性。我如何解决这个问题?我不喜欢使用ExpandoObjects,而且我被限制在.NET4.0中

我的解决方案(还不起作用)是在每个行对象的列表/数组中添加一个wrapperobject,然后在代码中生成一个新的DataGridTemplateColumn,其中combobox和textbox与数组中的这个wrapperobject有数据绑定。在XAML中,这看起来像,但我无法将0更改为1,2,3,。。。 我可以在代码隐藏中执行此操作,但我不知道如何将其绑定到WrapperObjectList[X].Value

下面是一个简化的示例,希望有助于理解我想要实现的目标:

我有一个datagrid,它绑定到带有RowObjects[rowobject表示1行..;)]的observablecollection。第一列是固定的,因此它绑定到RowObject中的属性

现在,我必须在此之后添加动态数量的列。这取决于用户选择了多少项(本例中没有,但您会明白这一点)。我将此操作替换为单击按钮

对于每个列,我创建一个wrapperobject,并将其添加到RowObject中的另一个observablecollection中。这给了我一点灵活性,因为我事先不知道会添加多少列。此包装器对象包含我需要显示的值

此外,我需要将这个包装器对象绑定到我的组合框中的一个选择。因此,如果我编辑一行,我从组合框中选择一个值,然后这个选择的值必须显示(设置)在celltemplate的文本框中

示例代码:

代码隐藏:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        LoadData();


        this.DataContext = RowList;

    }

    private void LoadData()
    {
        RowList = new ObservableCollection<RowObject>();
        WrapperObject lWrapperObject1 = new WrapperObject();
        lWrapperObject1.Value = 1;
        WrapperObject lWrapperObject2 = new WrapperObject();
        lWrapperObject2.Value = 2;

        WrapperObject lWrapperObject3 = new WrapperObject();
        lWrapperObject3.Value = 3;
        WrapperObject lWrapperObject4 = new WrapperObject();
        lWrapperObject4.Value = 4;

        WrapperObject lWrapperObject6 = new WrapperObject();
        lWrapperObject6.Value = 6;
        WrapperObject lWrapperObject8 = new WrapperObject();
        lWrapperObject6.Value = 8;

        RowObject lRowObject1 = new RowObject();
        lRowObject1.RowObjectName = "RowObject1";
        lRowObject1.WrapperCollection.Add(lWrapperObject1);
        lRowObject1.WrapperCollection.Add(lWrapperObject2);
        lRowObject1.WrapperCollection.Add(lWrapperObject6);

        RowObject lRowObject2 = new RowObject();
        lRowObject2.RowObjectName = "RowObject2";
        lRowObject2.WrapperCollection.Add(lWrapperObject3);
        lRowObject2.WrapperCollection.Add(lWrapperObject4);
        lRowObject2.WrapperCollection.Add(lWrapperObject8);

        RowList.Add(lRowObject1);
        RowList.Add(lRowObject2);


    }

    public ObservableCollection<RowObject> RowList { get; set; }


    private void Button_Click(object sender, RoutedEventArgs e)
    {
        DataGridTemplateColumn lTemplateColumn = new DataGridTemplateColumn();
        lTemplateColumn.Header = "NewDynamicColumn";
        var lMyCellTemplate= (DataTemplate)Resources["myCellTemplate"];
        var lMyCellEditingTemplate = (DataTemplate)Resources["myCellEditingTemplate"];

        // Text="{Binding WrapperCollection[1].Value}" ????

        lTemplateColumn.CellTemplate =lMyCellTemplate;
        lTemplateColumn.CellEditingTemplate = lMyCellEditingTemplate;
        this.MyGrid.Columns.Add(lTemplateColumn);
    }
}

public class RowObject : INotifyPropertyChanged
{

    public RowObject()
    {
        WrapperCollection = new ObservableCollection<WrapperObject>();
        ComboBoxList = new List<string>();
        ComboBoxList.Add("10");
        ComboBoxList.Add("20"); 
    }

    public ObservableCollection<WrapperObject> WrapperCollection { get; set; }

    private string fRowObjectName;

    public string RowObjectName
    {
        get { return fRowObjectName; }
        set
        {
            fRowObjectName = value;
            RaisePropertyChanged("RowObjectName");
        }
    }

    public List<string> ComboBoxList { get; set; }

    #region Notify property changed
    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion

}

public class WrapperObject : INotifyPropertyChanged
{
    private int fValue;

    public int Value 
    { 
        get {return fValue;}
        set
        {
            fValue = value;
            RaisePropertyChanged("Value");
        }
    }

    #region Notify property changed
    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion
}
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
LoadData();
this.DataContext=行列表;
}
私有void LoadData()
{
行列表=新的ObservableCollection();
WrapperObject LwrapperObject 1=新WrapperObject();
lWrapperObject1。值=1;
WrapperObject LwrapPerObject 2=新的WrapperObject();
LwrapPerObject 2.值=2;
WrapperObject lWrapperObject3=新的WrapperObject();
LwrapPerObject 3.值=3;
WrapperObject LwrapPerObject 4=新的WrapperObject();
LwrapPerObject 4.值=4;
WrapperObject lWrapperObject6=新的WrapperObject();
lWrapperObject6。值=6;
WrapperObject LwrapPerObject 8=新的WrapperObject();
lWrapperObject6.值=8;
RowObject lRowObject1=新的RowObject();
lRowObject1.RowObjectName=“RowObject1”;
lRowObject1.WrapperCollection.Add(lWrapperObject1);
lRowObject1.WrapperCollection.Add(lWrapperObject2);
lRowObject1.WrapperCollection.Add(lWrapperObject6);
RowObject lRowObject2=新的RowObject();
lRowObject2.RowObjectName=“RowObject2”;
lRowObject2.WrapperCollection.Add(lWrapperObject3);
lRowObject2.WrapperCollection.Add(lWrapperObject4);
lRowObject2.WrapperCollection.Add(lWrapperObject8);
添加(lRowObject1);
添加(lRowObject2);
}
公共ObservableCollection行列表{get;set;}
私有无效按钮\u单击(对象发送者,路由目标e)
{
DataGridTemplateColumn lTemplateColumn=新DataGridTemplateColumn();
lTemplateColumn.Header=“NewDynamicColumn”;
var lMyCellTemplate=(DataTemplate)资源[“myCellTemplate”];
var lMyCellEditingTemplate=(DataTemplate)资源[“myceleditingtemplate”];
//Text=“{Binding WrapperCollection[1]。Value}”????
lTemplateColumn.CellTemplate=lMyCellTemplate;
lTemplateColumn.CellEditingTemplate=lMyCellEditingTemplate;
this.MyGrid.Columns.Add(lTemplateColumn);
}
}
公共类RowObject:INotifyPropertyChanged
{
公共行对象()
{
WrapperCollection=新的ObservableCollection();
ComboBoxList=新列表();
ComboBoxList.添加(“10”);
ComboBoxList.添加(“20”);
}
公共ObservableCollection包装器集合{get;set;}
私有字符串名称;
公共字符串RowObjectName
{
获取{return fRowObjectName;}
设置
{
fRowObjectName=值;
RaisePropertyChanged(“RowObjectName”);
}
}
公共列表ComboxList{get;set;}
#区域通知属性已更改
公共事件属性更改事件处理程序属性更改;
public void RaisePropertyChanged(字符串propertyName)
{
if(PropertyChanged!=null)
{
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
#端区
}
公共类包装器对象:INotifyPropertyChanged
{
私人价值;
公共整数值
{ 
获取{return fValue;}
设置
{
fValue=价值;
提升财产变更(“价值”);
}
}
#区域通知属性已更改
公共事件属性更改事件处理程序属性更改;
public void RaisePropertyChanged(字符串propertyName)
{
if(PropertyChanged!=null)
{
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
#端区
}
Xaml:


<Window.Resources>
    <DataTemplate x:Key="myCellTemplate">
        <TextBlock Text="{Binding WrapperCollection[1].Value}" />
    </DataTemplate>

    <DataTemplate x:Key="myCellEditingTemplate">
        <ComboBox ItemsSource="{Binding ComboBoxList}" />
    </DataTemplate>
</Window.Resources>

<StackPanel>
    <DataGrid   x:Name="MyGrid" 
                AutoGenerateColumns="False"
                ItemsSource="{Binding}"
                >
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding RowObjectName}"/>
            <DataGridTextColumn Header="ExampleColumn1" Binding="{Binding WrapperCollection[0].Value}"/>
            <DataGridTemplateColumn Header="ExampleColumn2" CellTemplate="{StaticResource myCellTemplate}" CellEditingTemplate="{StaticResource myCellEditingTemplate}"/>           
        </DataGrid.Columns>
    </DataGrid>
    <Button Content="Click" Click="Button_Click" Width="100" Margin="20"/>
</StackPanel>
    public DataTemplate CreateDataTemplate(Type type, int aNumber)
    {
        StringReader stringReader = new StringReader(
        @"<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""> 
        <" + type.Name + @" Text=""{Binding WrapperCollection[" + aNumber.ToString() + @"].Value}""/> 
    </DataTemplate>");
        XmlReader xmlReader = XmlReader.Create(stringReader);
        return XamlReader.Load(xmlReader) as DataTemplate;
    }

{
    ...
    TextBlock textBlock = new TextBlock();
    var lMyCellTemplate = CreateDataTemplate(textBlock.GetType(), Counter);
}