Лучший способ программной блокировки / отключения нескольких элементов управления пользовательского интерфейса на ленточной панели

#c# #excel #vsto #ribbon

#c# #excel #vsto #лента

Вопрос:

Мне было интересно, каким был бы лучший способ реализовать блокировку / отключение множества элементов управления пользовательского интерфейса ленты одним щелчком мыши?

В настоящее время мой подход довольно прост и прост:

 private void tbtnLock_Click(object sender, RibbonControlEventArgs e)
       {
           if (tbtnLock.Checked)
           {
               control1.Enabled = false;
               control2.Enabled = false;
               control3.Enabled = false;
               //...
               //controlN.Enabled = false;
           }
           else
           {
               control1.Enabled = true;
               control2.Enabled = true;
               control3.Enabled = true;
               //...
               //controlN.Enabled = true;
           }
       }
  

Я думаю, что все в порядке, если у нас будет всего несколько элементов управления, но как только мы добавим все больше и больше элементов управления на ленточную панель, я не думаю, что было бы хорошей практикой кодирования делать вещи, подобные описанным выше.

Есть ли какой-нибудь более чистый и аккуратный подход к этому? Могу ли я получить коллекцию всех элементов управления на ленточной панели? Надеюсь, кто-нибудь может дать мне несколько советов здесь? Большое спасибо.

Редактировать:

Пересмотренный код ниже:

 private void tbtnLock_Click(object sender, RibbonControlEventArgs e)
        {
            toggleUILockState();
        }
private void toggleUILockState()
        {
            if (group1.Items != null)
            {
                foreach (RibbonControl c in group1.Items)
                {
                    if (c.Name != "tbtnLock")
                    {
                        c.Enabled = !tbtnLock.Checked;
                    }
                }
            }
        }
  

Я думаю, что это выглядит намного лучше, чем предыдущая версия. Спасибо всем за помощь.

Комментарии:

1. Что происходит, когда вы просто отключаете саму ленточную панель?

2. Но мне нужно оставить кнопку блокировки доступной.

3. Имейте в виду, что вы не будете перебирать RibbonControl s, включенные в RibbonBox es

Ответ №1:

Ну, конечно, первым шагом к улучшению кода было бы удалить оператор if и присвоить включенному состоянию элемента управления непосредственно проверенное состояние элемента управления tbtnLock, например…

 control1.Enabled = !tbtnLock.Checked;
control2.Enabled = !tbtnLock.Checked;
  

это сократило бы ваш код, если бы сразу наполовину. Возможно, вы захотите сначала назначить это bool, если захотите выполнить дополнительную обработку позже (возможно, какой-то другой объект помогает определить состояние блокировки, например)

 bool isEnabled = !tbtnLock.Checked;

control1.Enabled = isEnabled;
control2.Enabled = isEnabled;
  

Кроме того, мне нужно было бы знать, какой элемент управления «лента» вы используете. У вас есть ссылка?

Но, как вы намекнули, я бы хотел взглянуть на попытку найти набор элементов управления, перебрать их, проверить, не является ли элемент управления tbtnLock, и отключить / включить по мере необходимости.

Кроме того, я бы рекомендовал переместить весь этот код в функцию за пределами дескриптора события, на случай, если вам нужно вызвать этот метод из другого кода. Что-то вроде…

 private void tbtnLock_Click(object sender, RibbonControlEventArgs e)
{
   UpdateRibbonState();
}

private void UpdateRibbonState(){
   //Code goes here
}
  

РЕДАКТИРОВАТЬ: предполагается, что «группа» (как описано в комментариях) имеет набор элементов управления…

 foreach(Control c in group.Controls)
{
   if(c.Name != "tbtnLock")
   {
      c.Enabled = !tbtnLock.Checked;
   }
}
  

Я не знаком ни с одним встроенным.Чистые элементы управления лентой и поскольку нет ссылки на сторонний набор) Я делаю лучшее предположение о свойствах, доступных для «группы»

Комментарии:

1. спасибо за подробное объяснение. действительно ценится. элементы управления, которые я использую, — это просто кнопки ленты, переключатели. в будущем на ленту могут быть добавлены другие типы элементов управления. Также я в значительной степени сгруппировал эти кнопки в 1 группу (кнопка блокировки тоже находится в той же группе).

2. @woodykiddy: посмотрите мое редактирование, не уверен, что оно будет работать в том виде, в каком оно есть, но, надеюсь, укажет вам правильное направление

Ответ №2:

Похоже, вы могли бы поместить все свои элементы управления пользовательского интерфейса в один список, а затем повторить его, чтобы включить / отключить их все сразу. Что-то вроде (непроверенный / псевдокод):

 List<RibbonBase> listMyControls = new List<RibbonBase>()
{
  control1, control2, control3, ... , controlN
};

foreach (var control in listMyControls)
{
  control.Enabled = !tbtnLock.Checked;
}
  

Комментарии:

1. хм, очень поучительно. Но будет ли что-то по-другому, если я выберу ArrayList вместо List?

2. Если вы не застряли в .NET 1.0 или что-то в этом роде, я бы никогда не использовал ArrayList. У списков больше возможностей, они поддерживают тип, и с ними очень легко работать.

Ответ №3:

Вот некоторый код, чтобы распространить это на всю вкладку.

     /// <summary>
    /// Enable or Disable all buttons in all groups of the RibbonTab to match toggleButtonActive
    /// toggleButtonActive remains enabled
    /// </summary>
    /// <param name="enabled"></param>
    private void SetUILockState(bool enabled)
    {
        foreach (RibbonGroup group in myRibbonTab.Groups)
        {
            if (group.Items != null)
            {
                foreach (RibbonControl c in group.Items)
                {
                    if (c.Name != "toggleButtonActive")
                    {
                        c.Enabled = enabled;
                    }
                }
            }

        }
        // TODO handle right click menus as well
    }
  

Комментарии:

1. У меня есть две догадки по приведенному выше ответу: 1) Для некоторых RibbonControls вам нужно сделать больше / больше, чем установить «Enabled = false». Например. для SplitButton вы должны установить «SplitButton. ButtonEnabled = false» 2) Функция отключения должна быть рекурсивной, потому что у вас могут быть дочерние элементы управления, например, в элементе управления RibbonMenu.

2. Если меню отключено, действительно ли имеет значение, если его дочерние элементы не отключены? Я не сталкивался с разделением кнопки, но это кажется неудачным отклонением интерфейса, если это правда.

3. К сожалению, я это сделал (столкнулся с случаем SplitButton 🙂 Возможно, было бы лучше отключить все дочерние элементы RibbonMenu, потому что каждая кнопка RibbonButton может быть помещена, например, на панель быстрого доступа или может использоваться в других местах пользовательскими настройками ленты.