【问题标题】:Failing to generate dynamic textbox on radiobutton click in WPF无法在 WPF 中单击单选按钮时生成动态文本框
【发布时间】:2012-10-21 02:19:01
【问题描述】:

我正在开发一个 WPF 应用程序,我必须首先生成 4 个单选按钮,一旦完成,我需要在每个按钮单击时生成文本框和标签。

  • 生成 4 个具有不同 Content 的单选按钮
  • 在单击每个按钮时,根据单击的按钮生成 8 个具有不同 Content 的标签,并生成 64 个只读文本框,每个标签都有 8 个与之关联的文本框。即 8 x 8

我通过以下方式在某种程度上取得了成功:

XAML:

在我的 xaml 中,我将网格分为 2 行。第一行将有 4 个单选按钮。第二行将分为 2 列,其中第一列将有 8 个动态标签,第二列将有 64 个文本框。即每行 8 个。

<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类:这里设置这个类的DataContext

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 类:

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

因此,如果您注意到上面的 viewmodel 类,Index 会给我单击的单选按钮,我可以根据计算生成具有不同值的标签。十六进制转换完成。

这是要求:

  • 当我单击单选按钮时,标签将显示在 Grid.Column="0" 中,但我希望文本框也相应放置。如前所述,每次单击按钮将显示 64 个框,每个标签 8 个。文本框必须显示在 Grid.Column="1" 中。

  • 当我单击单选按钮时,会显示标签。当我单击下一个按钮时,标签会再次显示。但之前显示的标签不会被清除。我想在显示新标签之前清除它们。

  • 在启动时,必须选中第一个单选按钮,并且必须显示关联的标签 + 文本框。

我在 C++ 中创建文本框的示例代码:

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

截图如下: 请帮忙:)

【问题讨论】:

标签: c# .net wpf dynamic mvvm


【解决方案1】:

我会为此采取不同的方法:

  • 您的无线电虚拟机没问题,但它们也应该是一个 Children 集合,包含网格中的每个“行”,而这些“行”又包含一个“Title”属性(您要放在标签上的那个)和8 个字符串值的列表,这些值将显示在文本框中。比如:

主视图模型

  1. -> Radio Vms 列表
  2. -> 选定的无线电 VM
    1. -> 子“行”列表
      1. -> 行标签(字符串属性)
      2. -> 字符串值列表

那么您只需要 2 个项目控件:1 个用于绘制所有“行”以及每行内部、一个标签和第二个 ItemsControl(在 ItemsPanelTemplate 中使用水平 StackPanel 来绘制文本框)

【讨论】:

  • 嗯,这似乎是个好主意。如果您能用代码演示将不胜感激:)
猜你喜欢
  • 1970-01-01
  • 2012-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-09
  • 1970-01-01
相关资源
最近更新 更多