代码改变世界

RadioButton分组的实现

2010-11-22 11:15  Clingingboy  阅读(14592)  评论(1编辑  收藏  举报

 

 

XAML如下

    <StackPanel>
        <RadioButton GroupName="colorgrp">Red</RadioButton>
        <RadioButton GroupName="colorgrp">Blue</RadioButton>
        <RadioButton GroupName="numgrp">1</RadioButton>
        <RadioButton GroupName="numgrp">2</RadioButton>
        <RadioButton>4</RadioButton>
        <RadioButton>5</RadioButton>
    </StackPanel>

在一个Panel下,若没有指定GroupName则为一组,指定了GroupName为另外一组.

逻辑:一组内,选中一个Button取消其他的Button选中状态.

在没有分组状态下

image

即把Button的父容器找出来,然后反选未指定GroupName的Button

分组概念

要把多个Button存为一组,即多个key,每个key对应一个列表,可以以HashTable为基础.

应该由内部控件来调用,否则可能会引起重复的问题

public class RadioGroup
{
    [ThreadStatic]
    private static Hashtable _groupNameToElements;

    public static void Register(string groupName, RadioButton radioButton)
    {
        if (_groupNameToElements == null)
        {
            _groupNameToElements = new Hashtable(1);
        }
        lock (_groupNameToElements)
        {
            ArrayList elements = (ArrayList)_groupNameToElements[groupName];
            if (elements == null)
            {
                elements = new ArrayList(1);
                _groupNameToElements[groupName] = elements;
            }
            else
            {
                PurgeDead(elements, null);
            }
            elements.Add(new WeakReference(radioButton));
        }
    }

    public static void Unregister(string groupName, RadioButton radioButton)
    {
        if (_groupNameToElements != null)
        {
            lock (_groupNameToElements)
            {
                ArrayList elements = (ArrayList)_groupNameToElements[groupName];
                if (elements != null)
                {
                    PurgeDead(elements, radioButton);
                    if (elements.Count == 0)
                    {
                        _groupNameToElements.Remove(groupName);
                    }
                }
            }
        }
    }

    private static void PurgeDead(ArrayList elements, object elementToRemove)
    {
        int index = 0;
        while (index < elements.Count)
        {
            WeakReference reference = (WeakReference)elements[index];
            object target = reference.Target;
            if ((target == null) || (target == elementToRemove))
            {
                elements.RemoveAt(index);
            }
            else
            {
                index++;
            }
        }
    }
}