简体   繁体   中英

Failing to generate dynamic textbox on radiobutton click in WPF

I am working on a WPF app where i have to generate 4 radiobuttons first and once I am done with it, I need to generate textboxes and labels on each button click.

  • Generate 4 Radiobuttons with different Content
  • On clicking each button, generate 8 labels with different Content based on clicked button and generate 64 textboxes which are read only in such a way that each label has 8 textboxes associated with it. ie 8 x 8

I have been successful to some extent by doing it as follows:

XAML:

In my xaml, I have divided the grid in 2 rows. The first row will have 4 radiobuttons. The second row will be divided into 2 columns where 1st columns will have 8 dynamic labels and 2nd column will have 64 textboxes. ie 8 in each row.

<Grid Grid.Row="0">                     

        <ItemsControl ItemsSource="{Binding Children}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical" >
                        <RadioButton Content="{Binding RadioBase}" Margin="0,10,0,0" IsChecked="{Binding BaseCheck}" GroupName="SlotGroup" />                            
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

        <Button Content="Refresh Regs" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" Margin="0" Width="100" Height="25" />
    </Grid>

<Grid Grid.Row="1">            

        <ItemsControl ItemsSource="{Binding Children}" Grid.Column="0">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <ItemsControl Visibility="{Binding IsRegisterItemsVisible, Converter={StaticResource BoolToVisibilityConv}}" ItemsSource="{Binding RegisterLabels}">
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Margin="50,20,0,0">
                                        <TextBlock Text="{Binding}"/>
                                    </StackPanel>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

        <ItemsControl ItemsSource="{Binding Children}" Grid.Column="1">
            // Textbox here
        </ItemsControl>
    </Grid>

FPGARadioWidgetViewModel Class: DataContext of this class is set here

public ObservableCollection<FPGAViewModel> Children { get; set; }

    public FPGARadioWidgetViewModel()
    {
        Children = new ObservableCollection<FPGAViewModel>();
        Children.Add(new FPGAViewModel() { RadioBase = "Base 0x0", ID = 0 });
        Children.Add(new FPGAViewModel() { RadioBase = "Base 0x40", ID = 1 });
        Children.Add(new FPGAViewModel() { RadioBase = "Base 0x80", ID = 2 });
        Children.Add(new FPGAViewModel() { RadioBase = "Base 0xc0", ID = 3 });            
    }

FPGAViewModel Class:

private bool sBaseCheck;
    public bool BaseCheck
    {
        get { return this.sBaseCheck; }
        set
        {
            this.sBaseCheck = value;
            Generatelabels(this, ID);
            this.OnPropertyChanged("BaseCheck");
        }
    }

    private static void Generatelabels(FPGAViewModel currentItem, int index)
    {
        int m_baseRegister = 0;

        if (index == 0)
        {                
            for (int i = 0; i < 0x40 / 8; i++)
            {
                int reg = (i * 8) + m_baseRegister;
                currentItem.RegisterLabels[i] = "Reg 0x" + reg.ToString("X");
                currentItem.IsRegisterItemsVisible = true;
            }
        }
        else if (index == 1)
        {
            m_baseRegister = 0x40 * index;
            for (int i = 0; i < 0x40 / 8; i++)
            {
                int reg = (i * 8) + m_baseRegister;
                currentItem.RegisterLabels[i] = "Reg 0x" + reg.ToString("X");
                currentItem.IsRegisterItemsVisible = true;
            }
        }
        // Similarly for Index 2 and Index = 3
    }

    private string[] registerLabels = new string[8];
    public string[] RegisterLabels { get { return registerLabels; } }

    private bool isRegisterItemsVisible = false;
    public bool IsRegisterItemsVisible
    {
        get { return isRegisterItemsVisible; }
        set
        {
            isRegisterItemsVisible = value;
            OnPropertyChanged("IsRegisterItemsVisible");
            OnPropertyChanged("RegisterLabels");
        }
    }        

    private string _RadioBase;
    public string RadioBase
    {
        get; set;
    }

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

So if you notice the above viewmodel class, Index gives me the radiobutton clicked and I am able to generate labels with different values based on calculation. Hexadecimal conversion is done.

Here is the requirement:

  • When I click a radiobutton, the labels are getting displayed in Grid.Column="0" but i want the textbox also to get placed accordingly. As described earlier, each button click will display 64 boxes, 8 for each label. Textbox must get displayed in Grid.Column="1" .

  • When i click a radibutton, label are displayed. When i click the next button, labels are displayed again. but the previous displayed labels are not cleared. I want to clear them before displaying new labels.

  • On startup, 1st radiobutton must be checked and associated label + textbox must be displayed.

Sample code I did in C++ where I was able to create textboxes:

for(i = 0; i < 0x40; i++)
{
    m_registerGetValue[i] = new TextEditor();
    m_registerGetValue[i]->setReadOnly(true);
    addAndMakeVisible(m_registerGetValue[i]);
}

Here is the screenshot: 有关更多详细信息 Please help :)

I would have taken a different approach for this:

  • you radio VMs are ok, but then they should also a Children collection, containing each of the "rows" in your grid, which in turn contained a "Title" property (the one you're putting on the label) and a List of the 8 string Values which are the ones you will show in your textboxes. Something like:

Main ViewModel

  1. -> List of Radio Vms
  2. -> Selected Radio VM
    1. -> List of Children "rows"
    2. Row
      1. -> Row Label (string property)
      2. -> List of string values

then you would only need 2 itemscontrols: 1 to draw all the "rows" and inside of each row, a label, and the second ItemsControl (with a horizontal StackPanel in the ItemsPanelTemplate to draw the textboxes)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM