как создать 25 кнопок не прописывая их в xaml в ручную и не нарушив подход mvvm c# wpf
сейчас кнопки создаются так но мне за это хотят сломать ноги
public ObservableCollection<Button> Buttons { get; private set; }
ObservableCollection<Button> CreateButtons(ObservableCollection<Button> but)
{
but = new ObservableCollection<Button>();
for (int i = 0 ; i < 25; i++)
{
btn[i] = new Button();
btn[i].CommandParameter = i;
btn[i].Background = Brushes.Blue;
btn[i].Command = ColorChange;
btn[i].BorderBrush= new SolidColorBrush(Colors.Black);
but.Add(btn[i]);
}
return but;
}
public SlotMineViewModel()//конструктор
{
Buttons = CreateButtons(Buttons);
}
xaml
<ItemsControl Grid.Column="0" Grid.ColumnSpan="5" ItemsSource="{Binding Buttons}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="5" Columns="5" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Text}" Command="{BindingCommand}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Ответы (1 шт):
ViewModel не должна управлять кнопками уж точно (их созданием как минимум).
За это должен отвечать View слой. У вас мысль правильная: использовать ItemsControl, но только почему-то вы решили, что в ObservableCollection нужно складывать сами кнопки, что не верно.
Допустим, что у нас есть ViewModel:
class ViewModel
{
public ObservableCollection<string> Buttons { get; }
public ViewModel()
{
Buttons = new ObservableCollection<string>();
foreach (var button in Enumerable.Range(0, 10))
{
Buttons.Add($"Button #{button + 1}");
}
}
}
В ObservableCollection у нас будут лежать только какие-то "бизнес" данные, в текущем примере - только названия кнопок.
Далее во View слое мы делаем биндинг на эту коллекцию и создаем кнопки:
<ItemsControl ItemsSource="{Binding Buttons}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Обратите внимание, что Content="{Binding}" сделано т.к. в элементе коллекции только строка, а не объект, к которому можно было бы обратиться по имени свойства.
Таким образом мы получаем на форме 10 кнопок:
UPD: пример с использованием какой-то бизнес сущности в ObservableCollection
BusinessButtonData:
class BusinessButtonData
{
public Guid Guid { get; set; }
public string Name { get; set; }
}
ViewModel:
class ViewModel
{
public ObservableCollection<BusinessButtonData> Buttons { get; }
public ViewModel()
{
Buttons = new ObservableCollection<BusinessButtonData>();
foreach (var button in Enumerable.Range(0, 10))
{
Buttons.Add(new BusinessButtonData { Guid = Guid.NewGuid(), Name = $"Button #{button + 1}" });
}
ButtonCommand = new DelegateCommand<BusinessButtonData>(ButtonClick); //где DelegateCommand - ваша реализация команды
}
public ICommand ButtonCommand { get; set; }
private void ButtonClick(BusinessButtonData buttonData)
{
MessageBox.Show($"Вы нажали кнопку: {buttonData.Name} с GUID = {buttonData.Guid}");
}
}
И итоговая View:
<ItemsControl ItemsSource="{Binding Buttons}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Name}"
Command="{Binding DataContext.ButtonCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
CommandParameter="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
