【问题标题】:Failing to clear previously displayed labels on radiobutton click in wpf无法清除以前在 wpf 中单击单选按钮时显示的标签
【发布时间】:2012-11-01 13:23:15
【问题描述】:

我正在基于单选按钮点击动态生成标签。好吧,我已经成功了,但是每次单击按钮时,它都会生成标签,但不会清除以前的状态。代码如下:

XAML:

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

单击单选按钮时,它会显示 8 个标签。当我单击第二个单选按钮时,它会显示另外 8 个并且不会清除前 8 个。基本上一次只必须显示所选单选按钮的 8 个标签。如何实现?

【问题讨论】:

    标签: c# .net wpf mvvm


    【解决方案1】:

    我不确定,但 WPF 可能会感到困惑,因为您正在为 RegisterLabels 触发 PropertyChanged,而数组对象本身没有改变,只有内容发生了变化。

    通常,如果您的集合在 WPF 中具有更改的内容,您可以改用 ObservableCollection,它支持 INofityCollectionChanged 在其包含的项目发生更改时通知 WPF(就像您对 Children 所做的那样)

    要么这样,要么每次在 GenerateLabels 中创建一个新数组,然后在最后将其分配给您的 RegisterLabels 属性。

    ps。为什么您的 GenerateLabels() 方法是静态的?如果它只是一个普通的实例方法会更干净,那么你就不必传入currentItemindex

    EDIT:第二种方法的示例(替换数组)

    public string[] RegisterLabels { get; private set; }
    
    private void Generatelabels()
    {
        string[] labels = new string[8];
        int baseRegister = 0x40 * ID;
    
        for (int i = 0; i < 8; i++)
        {
            int reg = (i * 8) + baseRegister;
            labels[i] = "Reg 0x" + reg.ToString("X");
        }
    
        RegisterLabels = labels;
        OnPropertyChanged("RegisterLabels");
    }
    

    【讨论】:

    • 感谢您的回复。可以用示例代码详细说明吗?我认为这真的很有帮助:)
    • @SteveWilson 这是我第三次看到您要求提供示例代码来执行此操作。我已经向您解释了创建对象之间需要的层次关系以实现此目的所需的心态。请不要偷懒,不要再问别人你做你的工作。 =)
    • @GazTheDestroyer:嗯,这肯定会按预期显示标签:) 但是当我单击其他 3 个单选按钮时,看起来 OnPropertyChanged 不会被触发。它仅显示第一个按钮的标签。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-08
    • 2012-12-13
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    相关资源
    最近更新 更多