Имею ряд кнопок, которые переключают страницу приложения. У кнопок есть 2 состояния, нажатая и нет, для каждого состояния реализован стиль Menu
- обычная и MenuIn
- нажатая (то есть у пользователя открыта сейчас именно эта страница). В стилях изменяется только цвет.
Сейчас у меня каждая кнопка привязана к обработчику, который с помощью switch
, по названию кнопки выполняет необходимые действия, а именно открывает нужную страницу, задает всем не активным кнопкам стиль Menu
и кнопке текущего раздела задает стиль MenuIn
. В итоге у меня получается огромная портянка повторяющихся строк.
Как грамотно сократить код, может в стиле как то определять нажата кнопка или нет, может еще что?
private void ButtonEvent(string name)
{
switch (name)
{
case "ChangeBg":
BackgroundEvent.Restart();
break;
case "HomeBtn":
HomeBtn.Style = (Style) Application.Current.Resources["MenuIn"];
NewsBtn.Style = (Style) Application.Current.Resources["Menu"];
AlertsBtn.Style = (Style) Application.Current.Resources["Menu"];
InvasionsBtn.Style = (Style) Application.Current.Resources["Menu"];
SettingsBtn.Style = (Style) Application.Current.Resources["Menu"];
InfoBtn.Style = (Style) Application.Current.Resources["Menu"];
TradeBtn.Style = (Style) Application.Current.Resources["Menu"];
ActMissionsBtn.Style = (Style) Application.Current.Resources["Menu"];
MainFrame.Navigate(new Uri("View/HomePage.xaml", UriKind.Relative));
break;
case "NewsBtn":
HomeBtn.Style = (Style) Application.Current.Resources["Menu"];
NewsBtn.Style = (Style) Application.Current.Resources["MenuIn"];
AlertsBtn.Style = (Style) Application.Current.Resources["Menu"];
InvasionsBtn.Style = (Style) Application.Current.Resources["Menu"];
SettingsBtn.Style = (Style) Application.Current.Resources["Menu"];
InfoBtn.Style = (Style) Application.Current.Resources["Menu"];
TradeBtn.Style = (Style) Application.Current.Resources["Menu"];
ActMissionsBtn.Style = (Style) Application.Current.Resources["Menu"];
//MyPopup.IsOpen = true;
MainFrame.Navigate(new Uri("View/NewsPage.xaml", UriKind.Relative));
break;
case "AlertsBtn":
HomeBtn.Style = (Style) Application.Current.Resources["Menu"];
NewsBtn.Style = (Style) Application.Current.Resources["Menu"];
AlertsBtn.Style = (Style) Application.Current.Resources["MenuIn"];
InvasionsBtn.Style = (Style) Application.Current.Resources["Menu"];
SettingsBtn.Style = (Style) Application.Current.Resources["Menu"];
InfoBtn.Style = (Style) Application.Current.Resources["Menu"];
TradeBtn.Style = (Style) Application.Current.Resources["Menu"];
ActMissionsBtn.Style = (Style) Application.Current.Resources["Menu"];
//MyPopup.IsOpen = false;
//BodyFrame.Navigate(new Uri("Pages/AlertsPage.xaml", UriKind.Relative));
break;
case "TradeBtn":
HomeBtn.Style = (Style) Application.Current.Resources["Menu"];
NewsBtn.Style = (Style) Application.Current.Resources["Menu"];
AlertsBtn.Style = (Style) Application.Current.Resources["Menu"];
InvasionsBtn.Style = (Style) Application.Current.Resources["Menu"];
SettingsBtn.Style = (Style) Application.Current.Resources["Menu"];
InfoBtn.Style = (Style) Application.Current.Resources["Menu"];
TradeBtn.Style = (Style) Application.Current.Resources["MenuIn"];
ActMissionsBtn.Style = (Style) Application.Current.Resources["Menu"];
//BodyFrame.Navigate(new Uri("Pages/TradePage.xaml", UriKind.Relative));
break;
case "InvasionsBtn":
HomeBtn.Style = (Style) Application.Current.Resources["Menu"];
NewsBtn.Style = (Style) Application.Current.Resources["Menu"];
AlertsBtn.Style = (Style) Application.Current.Resources["Menu"];
InvasionsBtn.Style = (Style) Application.Current.Resources["MenuIn"];
SettingsBtn.Style = (Style) Application.Current.Resources["Menu"];
InfoBtn.Style = (Style) Application.Current.Resources["Menu"];
TradeBtn.Style = (Style) Application.Current.Resources["Menu"];
ActMissionsBtn.Style = (Style) Application.Current.Resources["Menu"];
//BodyFrame.Navigate(new Uri("Pages/InvasionsPage.xaml", UriKind.Relative));
break;
case "InfoBtn":
HomeBtn.Style = (Style) Application.Current.Resources["Menu"];
NewsBtn.Style = (Style) Application.Current.Resources["Menu"];
AlertsBtn.Style = (Style) Application.Current.Resources["Menu"];
InvasionsBtn.Style = (Style) Application.Current.Resources["Menu"];
SettingsBtn.Style = (Style) Application.Current.Resources["Menu"];
InfoBtn.Style = (Style) Application.Current.Resources["MenuIn"];
TradeBtn.Style = (Style) Application.Current.Resources["Menu"];
ActMissionsBtn.Style = (Style) Application.Current.Resources["Menu"];
//BodyFrame.Navigate(new Uri("Pages/InfoPage.xaml", UriKind.Relative));
break;
case "SettingsBtn":
HomeBtn.Style = (Style) Application.Current.Resources["Menu"];
NewsBtn.Style = (Style) Application.Current.Resources["Menu"];
AlertsBtn.Style = (Style) Application.Current.Resources["Menu"];
InvasionsBtn.Style = (Style) Application.Current.Resources["Menu"];
InfoBtn.Style = (Style) Application.Current.Resources["Menu"];
SettingsBtn.Style = (Style) Application.Current.Resources["MenuIn"];
TradeBtn.Style = (Style) Application.Current.Resources["Menu"];
ActMissionsBtn.Style = (Style) Application.Current.Resources["Menu"];
//BodyFrame.Navigate(new Uri("Pages/SettingsPage.xaml", UriKind.Relative));
break;
case "ActMissionsBtn":
HomeBtn.Style = (Style) Application.Current.Resources["Menu"];
NewsBtn.Style = (Style) Application.Current.Resources["Menu"];
AlertsBtn.Style = (Style) Application.Current.Resources["Menu"];
InvasionsBtn.Style = (Style) Application.Current.Resources["Menu"];
InfoBtn.Style = (Style) Application.Current.Resources["Menu"];
SettingsBtn.Style = (Style) Application.Current.Resources["Menu"];
TradeBtn.Style = (Style) Application.Current.Resources["Menu"];
ActMissionsBtn.Style = (Style) Application.Current.Resources["MenuIn"];
//BodyFrame.Navigate(new Uri("Pages/ActiveMissionsPage.xaml", UriKind.Relative));
break;
}
}
Это выглядит неправильно семантически.
Во-первых, каждая кнопка должна быть ответственна за себя, посторонний код не должен быть нужен.
Затем, скорее всего у вас не должно быть разных стилей для разных состояний кнопки. Для того, чтобы поменять изображение, просто примените триггер. Нужные куски информации для триггера положите в attached property.
В результате получится что-то такое
<Style TargetType="ToggleButton" x:Key="MenuButton">
<Setter Property="Width" Value="24"/> <!-- или сколько там надо -->
<!-- остальные свойства -->
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="Pink"/>
<!-- и так далее -->
</Trigger>
</Style.Triggers>
</Style>
Необходимость в ButtonEvent
отпадает.
Для того, чтобы набор ToggleButton
'ов вёл себя как RadioButton
'ы, можно взять RadioButton
'ы и застилизовать их:
<Grid>
<Grid.Resources>
<Style TargetType="ToggleButton" x:Key="MenuButton"
BasedOn="{StaticResource {x:Type ToggleButton}}">
<Setter Property="Width" Value="30"/>
<Setter Property="Height" Value="30"/>
<!-- остальная часть стиля -->
</Style>
</Grid.Resources>
<StackPanel Orientation="Vertical" Width="30">
<RadioButton Style="{StaticResource MenuButton}" GroupName="First"/>
<RadioButton Style="{StaticResource MenuButton}" GroupName="First"/>
<RadioButton Style="{StaticResource MenuButton}" GroupName="First"/>
<Grid Height="10"/>
<RadioButton Style="{StaticResource MenuButton}" GroupName="Second"/>
<RadioButton Style="{StaticResource MenuButton}" GroupName="Second"/>
<RadioButton Style="{StaticResource MenuButton}" GroupName="Second"/>
</StackPanel>
</Grid>
Чтобы привязать команды к каждой кнопке, я бы сделал так. Во-первых, в DataContext
'е (то есть, VM) положил бы коллекцию команд.
Вместо ручного создания кнопок взял бы ItemsControl
:
<ItemsControl ItemsSource="{Binding Commands}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Style="{StaticResource MenuButton}" GroupName="First"
Command="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
По нажатию кнопки вызывалась бы команда, а она уж пусть решает, что делать дальше.
Если ваш контрол — на самом деле ToolBar
, вы можете использовать ToolBar
вместо ItemsControl
'а.
<ToolBarTray Orientation="Vertical">
<ToolBar ItemsSource="{Binding Commands}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Style="{StaticResource MenuButton}" GroupName="First"
Command="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ToolBar>
</ToolBarTray>
Можно попробовать засунуть все кнопки в коллекцию myButtons
, тогда получается что-то вроде:
private void ButtonEvent(string name)
{
if (name == "ChangeBg")
{
BackgroundEvent.Restart()
return;
}
var myButtons = new[] { HomeBtn, NewsBtn, AlertsBtn, InvasionsBtn,
SettingsBtn, InfoBtn, TradeBtn, ActMissionsBtn };
foreach(var element in myButtons)
{
if (element.Name == name)
element.Style = (Style) Application.Current.Resources["MenuIn"];
else
element.Style = (Style) Application.Current.Resources["Menu"];
}
BodyFrame.Navigate(new Uri("Pages/" + name.Substring(0, name.Length - 3) + "Page.xaml", UriKind.Relative));
}
UPD: Как правильно заметил @Андрей, было бы намного лучше где-нибудь написать что-то вроде:
readonly Style MenuInStyle = (Style) Application.Current.Resources["MenuIn"];
readonly Style MenuStyle = (Style) Application.Current.Resources["Menu"]
Тогда код становится понятнее:
private void ButtonEvent(string name)
{
if (name == "ChangeBg")
{
BackgroundEvent.Restart()
return;
}
var myButtons = new[] { HomeBtn, NewsBtn, AlertsBtn, InvasionsBtn,
SettingsBtn, InfoBtn, TradeBtn, ActMissionsBtn };
foreach(var element in myButtons)
{
if (element.Name == name)
element.Style = MenuInStyle;
else
element.Style = MenuStyle;
}
BodyFrame.Navigate(new Uri("Pages/" + name.Substring(0, name.Length - 3) + "Page.xaml", UriKind.Relative));
}
private void ButtonEvent(string name)
{
HomeBtn.Style = (Style) Application.Current.Resources["Menu"];
NewsBtn.Style = (Style) Application.Current.Resources["Menu"];
AlertsBtn.Style = (Style) Application.Current.Resources["Menu"];
InvasionsBtn.Style = (Style) Application.Current.Resources["Menu"];
SettingsBtn.Style = (Style) Application.Current.Resources["Menu"];
InfoBtn.Style = (Style) Application.Current.Resources["Menu"];
TradeBtn.Style = (Style) Application.Current.Resources["Menu"];
ActMissionsBtn.Style = (Style) Application.Current.Resources["Menu"];
switch (name)
{
case "ChangeBg":
BackgroundEvent.Restart();
break;
case "HomeBtn":
HomeBtn.Style = (Style) Application.Current.Resources["MenuIn"];
MainFrame.Navigate(new Uri("View/HomePage.xaml", UriKind.Relative));
break;
case "NewsBtn":
NewsBtn.Style = (Style) Application.Current.Resources["MenuIn"];
MainFrame.Navigate(new Uri("View/NewsPage.xaml", UriKind.Relative));
break;
case "AlertsBtn":
AlertsBtn.Style = (Style) Application.Current.Resources["MenuIn"];
BodyFrame.Navigate(new Uri("Pages/AlertsPage.xaml", UriKind.Relative));
break;
case "TradeBtn":
TradeBtn.Style = (Style) Application.Current.Resources["MenuIn"];
BodyFrame.Navigate(new Uri("Pages/TradePage.xaml", UriKind.Relative));
break;
case "InvasionsBtn":
InvasionsBtn.Style = (Style) Application.Current.Resources["MenuIn"];
BodyFrame.Navigate(new Uri("Pages/InvasionsPage.xaml", UriKind.Relative));
break;
case "InfoBtn":
InfoBtn.Style = (Style) Application.Current.Resources["MenuIn"];
BodyFrame.Navigate(new Uri("Pages/InfoPage.xaml", UriKind.Relative));
break;
case "SettingsBtn":
SettingsBtn.Style = (Style) Application.Current.Resources["MenuIn"];
BodyFrame.Navigate(new Uri("Pages/SettingsPage.xaml", UriKind.Relative));
break;
case "ActMissionsBtn":
ActMissionsBtn.Style = (Style) Application.Current.Resources["MenuIn"];
BodyFrame.Navigate(new Uri("Pages/ActiveMissionsPage.xaml", UriKind.Relative));
break;
}
}
(Update) А вот такой пример подойдет?
private void ButtonEvent(string name)
{
if (name == "ChangeBg") {
BackgroundEvent.Restart();
return;
}
HomeBtn.Style = (Style) Application.Current.Resources[name != "HomeBtn" ? "Menu" : "MenuIn"];
NewsBtn.Style = (Style) Application.Current.Resources[name != "NewsBtn" ? "Menu" : "MenuIn"];
AlertsBtn.Style = (Style) Application.Current.Resources[name != "AlertsBtn" ? "Menu" : "MenuIn"];
InvasionsBtn.Style = (Style) Application.Current.Resources[name != "InvasionsBtn" ? "Menu" : "MenuIn"];
SettingsBtn.Style = (Style) Application.Current.Resources[name != "SettingsBtn" ? "Menu" : "MenuIn"];
InfoBtn.Style = (Style) Application.Current.Resources[name != "InfoBtn" ? "Menu" : "MenuIn"];
TradeBtn.Style = (Style) Application.Current.Resources[name != "TradeBtn" ? "Menu" : "MenuIn"];
ActMissionsBtn.Style = (Style) Application.Current.Resources[name != "ActMissionsBtn" ? "Menu" : "MenuIn"];
BodyFrame.Navigate(new Uri("Pages/" + name.Substring(0, name.Length - 3) + "Page.xaml", UriKind.Relative));
}
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Как получить доступ элементам MainPagexaml из созданного мной класса?
У меня есть проект, который находиться на диске "E" и bower работает отлично
В filterArraystatus_id при выборе двух одинаковых статусов падают одинаковые объекты
Как можно протестировать react компонент, пытаюсь создать класс things который наследуется от const MapServ, нет доступа к testMethod , getPage ни в переменной...