0

情况:

在 WPF/C# 中,我在 .xaml 文件的资源中使用以下 DataTemplate:

    <DataTemplate x:Key="lComboTestTemplate2">
        <ComboBox Name="lComboBoxInTemplate" VerticalAlignment="Center" ItemsSource="{Binding WrapperCollection[0].ComboBoxList}">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <CheckBox Width="20" />
                        <TextBlock Text="{Binding}" VerticalAlignment="Center" />
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </DataTemplate>

在后面的代码中,我没有遇到任何这样的问题:

DataTemplate lMyCellEditingTemplate = (DataTemplate)Resources["lComboTestTemplate2"];

而且我实际上能够使用它。当我实际尝试在后面的代码中实现相同的数据模板时,问题就出现了:

public DataTemplate CreateComboBoxDataTemplate(Type type, int aNumber)
    {
        StringReader stringReader = new StringReader(
        @"<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" > 
        <" + type.Name + @" ItemsSource=""{Binding WrapperCollection[" + aNumber.ToString() + @"].ComboBoxList}""> 
                    <" + type.Name + @".ItemTemplate>
                                <DataTemplate>
                                    <StackPanel Orientation=""HorizontalAlignment"">                                            
                                        <CheckBox Width=""20"" />       
                                        <TextBlock Text=""{Binding .}"" VerticalAlignment=""Center"" />                                    
                                    </StackPanel>
                                </DataTemplate>
                            </" + type.Name + @".ItemTemplate>
            </" + type.Name + @" >
        </DataTemplate>");
        XmlReader xmlReader = XmlReader.Create(stringReader);
        return XamlReader.Load(xmlReader) as DataTemplate;
    }

它编译并实际运行,但是当我开始编辑我的数据网格时,我得到一个空指针异常。

问题

我不知道为什么这是一个空指针,任何人都可以告诉我为什么后面的代码不起作用,而相同的 Xaml 代码起作用?

剩余代码/上下文

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

        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();
        lWrapperObject8.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; }

    public int Counter { get; set; }

    private void Button_Click(object sender, RoutedEventArgs e)
    {

        DataGridTemplateColumn lTemplateColumn = new DataGridTemplateColumn();
        lTemplateColumn.Header = "NewDynamicColumn";
        TextBlock textBlock = new TextBlock();
        var lMyCellTemplate = CreateDataTemplate(textBlock.GetType(), Counter);            
        var lMyCellEditingTemplate = CreateComboBoxDataTemplate(lCombo.GetType(), 0);
        //var lMyCellEditingTemplate = (DataTemplate)Resources["lComboTestTemplate2"];          
        lTemplateColumn.CellTemplate =lMyCellTemplate;
        lTemplateColumn.CellEditingTemplate = lMyCellEditingTemplate;
        this.MyGrid.Columns.Add(lTemplateColumn);
        Counter++;            
    }

  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;
    }

  public class RowObject : INotifyPropertyChanged
{
    public RowObject()
    {
        WrapperCollection = new ObservableCollection<WrapperObject>();
    }

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

    private string fRowObjectName;

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

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

}

public class WrapperObject : INotifyPropertyChanged
{

    public WrapperObject()
    {
        counter++;
        ComboBoxList = new List<string>();
        ComboBoxList.Add((10 + counter).ToString());
        ComboBoxList.Add((20 + counter).ToString());
    }

    private static int counter = 0;

    private int fValue;
    private List<String> fComboBoxList; 

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

    public List<string> ComboBoxList 
    {
        get { return fComboBoxList; }
        set
        {
            fComboBoxList = value;
            RaisePropertyChanged("ComboBoxList");
        }
    }

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

.Xaml

    <Window.Resources>

    <DataTemplate x:Key="lComboTestTemplate">
        <StackPanel Orientation="Horizontal">

            <CheckBox Width="20" />
            <TextBlock Text="{Binding WrapperCollection[1].ComboBoxList}" Width="100" />
        </StackPanel>
    </DataTemplate>

    <DataTemplate x:Key="lComboTestTemplate2">
        <ComboBox Name="lComboBoxInTemplate" VerticalAlignment="Center" ItemsSource="{Binding WrapperCollection[0].ComboBoxList}">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <CheckBox Width="20" />
                        <TextBlock Text="{Binding}" VerticalAlignment="Center" />
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </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}"/>-->
        </DataGrid.Columns>
    </DataGrid>
    <Button Content="Click" Click="Button_Click" Width="100" Margin="20"/>
</StackPanel>
4

0 回答 0