#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 может быть помещена, например, на панель быстрого доступа или может использоваться в других местах пользовательскими настройками ленты.