程序崩溃在WPF中创建动态生成的radiobuttons时

时间:2012-10-30 06:30:02

标签: c# .net wpf dynamic mvvm

我是C ++开发人员,最近我转到了C#。我正在使用MVVM模式开发一个wpf应用程序。我的xaml文件中有一个groupboxbox,我将其分为两列。一列包含动态生成的一组radiobuttons,其他列包含一个标签和许多组合框。

XAML:

<GroupBox Header="Daughter Cards" Height="Auto" HorizontalAlignment="Stretch" Margin="20,5,20,20" Name="groupBox2" VerticalAlignment="Stretch" Width="Auto">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />                        
                    <ColumnDefinition Width="220" />
                </Grid.ColumnDefinitions>

                <Grid Grid.Column="0">
                    <ItemsControl ItemsSource="{Binding SlotChildren}">
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <UniformGrid />
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>

                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <RadioButton Content="{Binding SlotButtons}" Margin="0,10,0,0" IsChecked="{Binding IsChecked}" GroupName="SlotGroup" Height="15" Width="80" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </Grid>                

                <Grid Grid.Column="1">                        
                        <ComboBox ItemsSource="{Binding DaughterBoardBoxList}" SelectedItem="{Binding SelectedDaughterBoardBoxList, Mode=TwoWay}" SelectedIndex="0" Height="23" HorizontalAlignment="Center" Margin="0" Name="comboBox5" VerticalAlignment="Center" Width="158" />
                        <ComboBox ItemsSource="{Binding DaughterVersionBoxList}" SelectedItem="{Binding SelectedDaughterVersionBoxList, Mode=TwoWay}" SelectedIndex="0" Height="23" HorizontalAlignment="Center" Margin="0" Name="comboBox6" VerticalAlignment="Center" Width="158" />
                        <ComboBox ItemsSource="{Binding DaughterSerialBoxList}" SelectedItem="{Binding SelectedDaughterSerialBoxList, Mode=TwoWay}" SelectedIndex="0" Height="23" HorizontalAlignment="Center" Margin="0" Name="comboBox7" VerticalAlignment="Center" Width="158" />                        
                        <Label Content="{Binding DaughterStatus}" Height="25" HorizontalAlignment="Center" Margin="0" Name="DaughterCardLabel" VerticalAlignment="Center" Width="170" />
                        <ComboBox Height="23" ItemsSource="{Binding I2CAddressList}" SelectedItem="{Binding SelectedI2CAddressList, Mode=TwoWay}" SelectedIndex="0" Grid.Row="0" HorizontalAlignment="Center" Margin="0,0,0,0" Name="comboBox1" VerticalAlignment="Center" Width="200" />
                        <ComboBox Height="23" ItemsSource="{Binding BoardBoxList}" SelectedItem="{Binding SelectedBoardBoxList, Mode=TwoWay}" SelectedIndex="0" Grid.Row="1" HorizontalAlignment="Center" Margin="0,0,0,0" Name="comboBox2" VerticalAlignment="Center" Width="200" />
                        <ComboBox Height="23" ItemsSource="{Binding VersionBoxList}" SelectedItem="{Binding SelectedVersionBoxList, Mode=TwoWay}" SelectedIndex="0" Grid.Row="2" HorizontalAlignment="Center" Margin="0,0,0,0" Name="comboBox3" VerticalAlignment="Center" Width="200" />
                        <ComboBox Height="23" ItemsSource="{Binding SerialBoxList}" SelectedItem="{Binding SelectedSerialBoxList, Mode=TwoWay}" SelectedIndex="0" Grid.Row="3" HorizontalAlignment="Center" Margin="0,0,0,0" Name="comboBox4" VerticalAlignment="Center" Width="200" />                
                </Grid>                                       
            </Grid> 
</GroupBox>

EEPROMViewModel类: xaml的DataContext设置为此类。在同一个班级:

Byte[] sendBuf = new Byte[256];
    Byte[] readBuf = new Byte[256];

    public ObservableCollection<EEPROMSlotViewModel> SlotChildren { get; set; }

    public ObservableCollection<string> _I2CAddressList;
    public ObservableCollection<string> _BoardBoxList;
    public ObservableCollection<string> _VersionBoxList;
    public ObservableCollection<string> _SerialBoxList;
    public ObservableCollection<string> _DBoardBoxList;
    public ObservableCollection<string> _DVersionBoxList;
    public ObservableCollection<string> _DSerialBoxList;       

    public EEPROMViewModel()
    {              

        SlotChildren = new ObservableCollection<EEPROMSlotViewModel>();
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "0 : None", ID = 0 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "1 : None", ID = 1 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "2 : None", ID = 2 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "3 : None", ID = 3 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "4 : None", ID = 4 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "5 : None", ID = 5 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "6 : None", ID = 6 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "7 : None", ID = 7 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "8 : None", ID = 8 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "9 : None", ID = 9 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "10 : None", ID = 10 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "11 : None", ID = 11 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "12 : None", ID = 12 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "13 : None", ID = 13 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "14 : None", ID = 14 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "15 : None", ID = 15 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "16 : None", ID = 16 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "17 : None", ID = 17 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "18 : None", ID = 18 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "19 : None", ID = 19 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "20 : None", ID = 20 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "21 : None", ID = 21 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "22 : None", ID = 22 });
        SlotChildren.Add(new EEPROMSlotViewModel() { SlotButtons = "23 : None", ID = 23 });

        var myboard = new[]
        {      
               "",
               "S1010012",   // redhook
               "S1010018",   // bavaria
               "S1010020"    // flying dog
        };

        var myVariant = new[]
        { 
               "",    
               "001A",
               "001B",
               "001C",
               "002A",
               "002B",
               "002C",
               "003A",
               "003B",
               "003C",
        };      

        _I2CAddressList = new ObservableCollection<string>();
        _BoardBoxList = new ObservableCollection<string>(myboard);
        _VersionBoxList = new ObservableCollection<string>(myVariant);
        _SerialBoxList = new ObservableCollection<string>();

        for (int i = 1; i < 200; i++)
        {
            _SerialBoxList.Add(i.ToString());
        }

        //List of I2C Address
        _I2CAddressList.Add("0x50");
        _I2CAddressList.Add("0x53");

        this.SelectedI2CAddressList = this._I2CAddressList[1];
        this.SelectedBoardBoxList = this.BoardBoxList[2];
        this.SelectedVersionBoxList = this.VersionBoxList[2];
        this.SelectedSerialBoxList = this.SerialBoxList[0];                       

        var myDBoards = new[]
        { 
               "",    
               "S1010013",
               "S1010014",
               "S1010015",
               "S1010017",
               "S1010019",
               "S1010021",
               "S1010023",
               "S1010026",
               "S1110029",
        };

        _DBoardBoxList = new ObservableCollection<string>(myDBoards);
        _DVersionBoxList = new ObservableCollection<string>(myVariant);
        _DSerialBoxList = new ObservableCollection<string>();

        for (int j = 1; j < 500; j++)
        {
            _DSerialBoxList.Add(j.ToString());
        }                     

    }              

    public ObservableCollection<string> I2CAddressList
    {
        get { return _I2CAddressList; }
        set
        {
            _I2CAddressList = value;
            OnPropertyChanged("I2CAddressList");
        }
    }

    private string _SelectedI2CAddressList;
    public string SelectedI2CAddressList
    {
        get { return _SelectedI2CAddressList; }
        set
        {
            _SelectedI2CAddressList = value;
            OnPropertyChanged("SelectedI2CAddressList");
        }
    }

    public ObservableCollection<string> BoardBoxList
    {
        get { return _BoardBoxList; }
        set
        {
            _BoardBoxList = value;
            OnPropertyChanged("BoardBoxList");
        }
    }

    private string _SelectedBoardBoxList;
    public string SelectedBoardBoxList
    {
        get { return _SelectedBoardBoxList; }
        set
        {
            _SelectedBoardBoxList = value;
            OnPropertyChanged("SelectedBoardBoxList");
        }
    }

    public ObservableCollection<string> VersionBoxList
    {
        get { return _VersionBoxList; }
        set
        {
            _VersionBoxList = value;
            OnPropertyChanged("VersionBoxList");
        }
    }

    private string _SelectedVersionBoxList;
    public string SelectedVersionBoxList
    {
        get { return _SelectedVersionBoxList; }
        set
        {
            _SelectedVersionBoxList = value;
            OnPropertyChanged("SelectedVersionBoxList");
        }
    }

    public ObservableCollection<string> SerialBoxList
    {
        get { return _SerialBoxList; }
        set
        {
            _SerialBoxList = value;
            OnPropertyChanged("SerialBoxList");
        }
    }

    private string _SelectedSerialBoxList;
    public string SelectedSerialBoxList
    {
        get { return _SelectedSerialBoxList; }
        set
        {
            _SelectedSerialBoxList = value;
            OnPropertyChanged("SelectedSerialBoxList");
        }
    }        

    char[] version = 
        {
                'A', 'U', 'D', 'I', 'E', 'N', 'C', 'E',         // name
                '0', '0', '0', '0', '0', '0', '0', '0' ,        // reserved,  firmware size
                '0', '0', '0', '0', '0', '0', '0', '0' ,        // board number
                '0', '0', '0', '0', '0', '0', '0', '0' ,        // variant, version, serial
                '0', '0', '0', '0', '0', '0', '0', '0'          // date code, reserved
        };        

    public ObservableCollection<string> DaughterBoardBoxList
    {
        get { return _DBoardBoxList; }
        set
        {
            _DBoardBoxList = value;
            OnPropertyChanged("DaughterBoardBoxList");
        }
    }

    public string _SelectedDBoardBoxList;
    public string SelectedDaughterBoardBoxList
    {
        get { return _SelectedDBoardBoxList; }
        set
        {
            _SelectedDBoardBoxList = value;
            OnPropertyChanged("SelectedDaughterBoardBoxList");
        }
    }

    public ObservableCollection<string> DaughterVersionBoxList
    {
        get { return _DVersionBoxList; }
        set
        {
            _DVersionBoxList = value;
            OnPropertyChanged("DaughterVersionBoxList");
        }
    }

    public string _SelectedDVersionBoxList;
    public string SelectedDaughterVersionBoxList
    {
        get { return _SelectedDVersionBoxList; }
        set
        {
            _SelectedDVersionBoxList = value;
            OnPropertyChanged("SelectedDaughterVersionBoxList");
        }
    }

    public ObservableCollection<string> DaughterSerialBoxList
    {
        get { return _DSerialBoxList; }
        set
        {
            _DSerialBoxList = value;
            OnPropertyChanged("DaughterSerialBoxList");
        }
    }

    private string _SelectedDSerialBoxList;
    public string SelectedDaughterSerialBoxList
    {
        get { return _SelectedDSerialBoxList; }
        set
        {
            _SelectedDSerialBoxList = value;
            OnPropertyChanged("SelectedDaughterSerialBoxList");
        }
    }

    private string _DaughterStatus = "Not Retrieved yet";
    public string DaughterStatus
    {
        get { return _DaughterStatus; }
        set
        {
            _DaughterStatus = value;
            OnPropertyChanged("DaughterStatus");
        }
    }          

EEPROMSlotViewModel类:

EEPROMViewModel mVMModel = new EEPROMViewModel();
private string _SlotButtons;
    public string SlotButtons
    {
        get; set;
    }

    private int _ID;
    public int ID
    {
        get; set;
    }

    private bool _isChecked;
    public bool IsChecked
    {
        get { return _isChecked; }
        set
        {
            _isChecked = value;
            OnSlotClick(ID);
            OnPropertyChanged("IsChecked");
        }
    }

public void OnSlotClick(int Index)
    {
        string label = string.Empty;
        if (Index >= 0 && Index < 24)
        {
            //getShortName(Index, label);
            if (label == string.Empty)
            {
                SlotButtons = Convert.ToString(Index + " : None");
            }
            else
            {
                SlotButtons = Convert.ToString(Index + " :" + label);
            }
        }

        if (label != string.Empty)
        {
            label += " - ";
            //getLongName(Index, label);
        }
        else
        {
            label = "No device found at this slot";
        }

        mVMModel.DaughterStatus = label; // displays it in the label
    }

当我尝试运行应用程序时,它崩溃并抛出异常作为stackoverflow。当我检查任何单选按钮并调用关节方法时,问题似乎出现在 EEPROMSlotViewModel 中。

我在这里犯的错误是什么? :( 请帮助:)

1 个答案:

答案 0 :(得分:1)

您的问题在mVMModel.DaughterStatus = label; // displays it in the label上,您可能在EEPROMSlotViewModel中实例化EEPROMViewModel类,这会导致无限循环。
要解决此问题,您需要访问您的parentVM,可以使用Interfaces来显示,只显示DaughterStatus,但快速回答如下:

向EEPROMSlotViewModel添加属性:

public EEPROMViewModel ParentVM
        {
            get { return _parentVm; }
            set
            {
                _parentVm = value;
                OnPropertyChanged("ParentVM");
            }
        }


而不是mVMModel.DaughterStatus = label;放ParentVM.DaughterStatus = label;
最后:

SlotChildren.Add(new EEPROMSlotViewModel() { ParentVM = this, SlotButtons = "0 : None", ID = 0 });