Создавать метки динамически при нажатии на динамически сгенерированный RadioButton в WPF

Я разработчик на C ++ и недавно перешел на wpf. Кажется, у меня возникла сложная ситуация, когда мне нужно динамически генерировать метки на основе щелчка радиокнопки. Здесь я покажу вам, как сначала я создал 4 переключателя.

XAML:

<Grid Grid.Row="0">           

        <ItemsControl ItemsSource="{Binding Children}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Vertical"
                    IsItemsHost="True" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>

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

    </Grid>

<Grid Grid.Row="1">
    <Label Content="{Binding name}" HorizontalAlignment="Center" VerticalAlignment="Center" />      
</Grid>

ViewModel:

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

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

        set
        {
            _ID = value;
            OnPropertyChanged("ID");
        }
    }

    private string _NAme;
    public string name
    {
        get
        {
            return _NAme;
        }

        set
        {
            _NAme= value;
            OnPropertyChanged("name");
        }
    }

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

        set
        {
            _RadioBase = value;
            OnPropertyChanged("RadioBase");
        }
    }

Класс AnotherViewModel:

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

Это дает мне 4 радиокнопки с содержимым, как указано выше. Теперь я хочу генерировать 8 меток при каждом щелчке радиокнопки. Я сделал это в своем приложении на C ++ следующим образом:

for(i = 0; i < 0x40 / 8; i++)
{
    reg = (i * 8);
    m_registerLabel[i] = new Label(String::empty, String("Reg 0x") + String::toHexString(reg));
    addAndMakeVisible(m_registerLabel[i]);
}

если вы заметили, он создаст 8 меток со значением Reg 0x0, Reg 0x8, Reg 0x10, Reg 0x18 и т. д., поскольку reg преобразуется в шестнадцатеричную строку. Я хочу создать что-то подобное, когда я нажимаю Base 0x0 при запуске.

Как я могу добиться этого в своем приложении ???


person StonedJesus    schedule 25.10.2012    source источник
comment
Я думаю, эта ссылка [Программно добавить элементы управления в форму WPF] [1] [1]: stackoverflow.com/questions/2814866/ поможет вам ..   -  person Rahul Ranjan    schedule 25.10.2012
comment
@RahulRanjan: Не совсем. Я следую шаблону MVVM.   -  person StonedJesus    schedule 25.10.2012


Ответы (1)


В вашем сеттере this.sBaseCheck вы можете сделать этот код.

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

Добавить 2 новых свойства ...

  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 static void Generatelabels(FPGAViewModel currentItem)
{
  for(i = 0; i < 0x40 / 8; i++)
  {
       reg = (i * 8);
       currentItem.RegisterLabels[i] = "Reg 0x" + String::toHexString(reg);
       currentItem.IsRegisterItemsVisible = true;
   }
}

В своем графическом интерфейсе свяжите их с другим ItemsControl в пределах ItemTemplate существующего ItemsControl.

        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Vertical">
                    <RadioButton 
                       Content="{Binding RadioBase}"
                       Margin="0,10,0,0"
                       IsChecked="{Binding BaseCheck}" 
                       Height="15" Width="80" 
                       HorizontalAlignment="Center" 
                       VerticalAlignment="Center"/>
                    <ItemsControl 
                           Visibility="{Binding IsRegisterItemsVisible,
                                Converter={StaticResource BoolToVisibilityConv}}" 
                           ItemsSource="{Binding RegisterLabels}">   
                       <ItemsControl.ItemTemplate>
                          <DataTemplate>
                             <TextBlock Text="{Binding}"/>
                           </DataTemplate>
                       </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
person WPF-it    schedule 25.10.2012
comment
Спасибо за ответ. Выдает ошибку на currentItem.RegisterLabel[i] = String("Reg 0x") + String::toHexString(reg); как ViewModel doesnt contain definition for RegisterLabel. и на String как string is a type but is used like a variable. - person StonedJesus; 29.10.2012
comment
Обновлено. Пожалуйста, примите это как псевдокод, поскольку я не разработчик на C ++. - person WPF-it; 29.10.2012
comment
Спасибо братан ..... Я удалил все ошибки, но приложение вылетает и выдает следующее: Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an exception.. Я предполагаю, что что-то не так с xaml - person StonedJesus; 29.10.2012
comment
Привет, привет! BoolToVisibilityConv - это реализация IValueConverter WPF для преобразования логического значения в видимость. ты это написал? - person WPF-it; 29.10.2012
comment
Я использовал его, он работает хорошо, но есть ошибка. Если я нажму 1-ю радиокнопку, нижние 3 кнопки станут невидимыми, а если я нажму 2-ю радиокнопку, то будут невидимы последние 2 кнопки и так далее. - person StonedJesus; 29.10.2012
comment
Если вы обратили внимание на мой вопрос, вы найдете label в Grid.Row="1". Это сетка, в которой я хочу отображать метки, созданные вашим кодом, а не внутри Grid.Row="0". Поскольку у вас текстовое поле, все в порядке :) Но отображать их в Grid.Row="1" было бы идеально :) - person StonedJesus; 29.10.2012