1

是否有一种标准方法可以以编程方式选择/检查一组单选按钮中的下一个单选按钮?我正在寻找的行为类似于分组在容器中的单选按钮的默认箭头键按下事件:当我按下箭头键时,会自动选择并检查下一个(或上一个)单选按钮。

4

4 回答 4

1

我是这样做的:

    var rads = panel1.Controls.OfType<RadioButton>(); // Get all radioButtons of desired panel

    rads.OrderBy(r => r.Top); // sort them. Please specify what you mean "next" here. I assume that you need next one at the bottom

    // find first checked and set checked for next one
    for (int i = 0; i < rads.Count()-1; i++) 
    {
        if (rads.ElementAt(i).Checked)
        {
            rads.ElementAt(i + 1).Checked = true; 
            return;
        }
    }
于 2013-01-16T11:58:44.520 回答
0

最快的解决方案:(如果您的应用程序有焦点......)

//assuming you are at the first radio button
SendKeys({DOWN});

更困难的解决方案:http: //msdn.microsoft.com/en-us/library/system.windows.automation.automationelement.findall.aspx

//Write method to get window element for the window you wish to manipulate
//Open an instance of notepad and the WindowTitle is: "Untitled - Notepad"
//you could use other means of getting to the Window element ...
AutomationElement windowElement = getWindowElement("Untitled - Notepad");

//Use System.Windows.Automation to find all radio buttons in the WindowElement
//pass the window element into this method
//This method will return all of the radio buttons in the element that is passed in
//however, if you have a Pane inside of the WIndow and then, the buttons are contained
//in the pane, you will have to get to the pane and then pass the pane into the findradiobuttons method
AutomationElementCollection radioButtons = FindRadioButtons(windowElement);

//could iterate through the radioButtons to determine which is selected...
//then select the next index etc.    

//then programmatically select the radio button
//pass the selected radioButton AutomationElement into a method that Invokes the Click etc.
clickButtonUsingUIAutomation(radioButtons[0]);

/// <summary> 
/// Finds all enabled buttons in the specified window element. 
/// </summary> 
/// <param name="elementWindowElement">An application or dialog window.</param>
/// <returns>A collection of elements that meet the conditions.</returns>
AutomationElementCollection FindRadioButtons(AutomationElement elementWindowElement)
{
    if (elementWindowElement == null)
    {
        throw new ArgumentException();
    }
    Condition conditions = new AndCondition(
      new PropertyCondition(AutomationElement.IsEnabledProperty, true),
      new PropertyCondition(AutomationElement.ControlTypeProperty, 
          ControlType.RadioButton)
      );

    // Find all children that match the specified conditions.
    AutomationElementCollection elementCollection = 
    elementWindowElement.FindAll(TreeScope.Children, conditions);
    return elementCollection;
}

    private AutomationElement getWindowElement(string windowTitle)
    {
        AutomationElement root = AutomationElement.RootElement;
        AutomationElement result = null;
        foreach (AutomationElement window in root.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window)))
        {
            try
            {
                if (window.Current.Name.Contains(windowTitle) && window.Current.IsKeyboardFocusable)
                {
                    result = window;
                    break;
                }
            }
            catch (Exception e)
            {
                throw;
            }
        }

        return result;
    }

    private void ClickButtonUsingUIAutomation(AutomationElement control)
    {
        // Test for the control patterns of interest for this sample. 
        object objPattern;
        ExpandCollapsePattern expcolPattern;

        if (true == control.TryGetCurrentPattern(ExpandCollapsePattern.Pattern, out objPattern))
        {
            expcolPattern = objPattern as ExpandCollapsePattern;
            if (expcolPattern.Current.ExpandCollapseState != ExpandCollapseState.LeafNode)
            {
                Button expcolButton = new Button();
                //expcolButton.Margin = new Thickness(0, 0, 0, 5);
                expcolButton.Height = 20;
                expcolButton.Width = 100;
                //expcolButton.Content = "ExpandCollapse";
                expcolButton.Tag = expcolPattern;
                expcolPattern.Expand();
                //SelectListItem(control, "ProcessMethods");
                //expcolButton.Click += new RoutedEventHandler(ExpandCollapse_Click);
                //clientTreeViews[treeviewIndex].Children.Add(expcolButton);
            }
        }
        TogglePattern togPattern;
        if (true == control.TryGetCurrentPattern(TogglePattern.Pattern, out objPattern))
        {
            togPattern = objPattern as TogglePattern;
            Button togButton = new Button();
            //togButton.Margin = new Thickness(0, 0, 0, 5);
            togButton.Height = 20;
            togButton.Width = 100;
            //togButton.Content = "Toggle";
            togButton.Tag = togPattern;
            togPattern.Toggle();
            //togButton.Click += new RoutedEventHandler(Toggle_Click);
            //clientTreeViews[treeviewIndex].Children.Add(togButton);
        }
        InvokePattern invPattern;
        if (true == control.TryGetCurrentPattern(InvokePattern.Pattern, out objPattern))
        {
            invPattern = objPattern as InvokePattern;
            Button invButton = new Button();
            //invButton.Margin = new Thickness(0);
            invButton.Height = 20;
            invButton.Width = 100;
            //invButton.Content = "Invoke";
            invButton.Tag = invPattern;
            //invButton.Click += new EventHandler(Invoke_Click);
            invPattern.Invoke();

            //clientTreeViews[treeviewIndex].Children.Add(invButton);
        }

    }
于 2013-01-16T03:35:02.373 回答
0

所以,似乎没有标准的方法来处理这个问题。我最终从 Andrey 的解决方案中获得灵感,并编写了一个可以从一组 RadioButton 中的任何特定 RadioButton 调用的扩展方法。

public static void CheckNextInGroup(this RadioButton radioButton, bool forward) {
    var parent = radioButton.Parent;
    var radioButtons = parent.Controls.OfType<RadioButton>();  //get all RadioButtons in the relevant container
    var ordered = radioButtons.OrderBy(i => i.TabIndex).ThenBy(i => parent.Controls.GetChildIndex(i)).ToList();  //Sort them like Windows does
    var indexChecked = ordered.IndexOf(radioButtons.Single(i => i.Checked)); //Find the index of the one currently checked
    var indexDesired = (indexChecked + (forward ? 1 : -1)) % ordered.Count;  //This allows you to step forward and loop back to the first RadioButton
    if (indexDesired < 0) indexDesired += ordered.Count;  //Allows you to step backwards to loop to the last RadioButton
    ordered[indexDesired].Checked = true;
}

然后,从可以访问您的特定 RadioButton 的任何地方,您可以检查其集合中的下一个或上一个 RadioButton。像这样:

radioButton1.CheckNextInGroup(true); //Checks the next one in the collection
radioButton1.CheckNextInGroup(false); //Checks the previous one in the collection
于 2013-01-16T21:16:26.503 回答
0

RadioButton每个容器只能检查一个。这就是单选按钮的意义所在。如果您想使用 aCheckBox代替,您可以使用以下代码:

foreach (CheckBox control in Controls.OfType<CheckBox>())
{
    control.Checked = true;
}

如果你想按顺序检查控件,你可以这样做

new Thread(() =>
{
    foreach (CheckBox control in Controls.OfType<CheckBox>())
    {
        control.BeginInvoke((MethodInvoker) (() => control.Checked = true));
        Thread.Sleep(500);
    }
}).Start();

再次阅读您的原始帖子,我正在努力理解您的意思。您能否详细说明,以便我更新我的回复?

于 2013-01-15T22:20:47.577 回答