I'm trying to add StatusBarItem
dynamically by using mvvm pattern but i don't know what to do.
If i write the code that i want to create in XAML file, it looks like this:
<StatusBar Grid.Row="2" DockPanel.Dock="Bottom">
<StatusBarItem HorizontalAlignment="Left">
<StatusBarItem Content="There's a sentence in it."/>
</StatusBarItem>
<StatusBarItem HorizontalAlignment="Right">
<StackPanel Orientation="Horizontal">
<StatusBarItem Content="Status 1" Background="Yellow" Margin="0 0 10 0"/>
<StatusBarItem Content="Status 2" Background="Red" Margin="0 0 10 0"/>
</StackPanel>
</StatusBarItem>
</StatusBar>
But I want to dynamically add 'StatusBarItem' on the right side.
Because i can see the status of the programs that are communicating with WPF program, and it can be multiple.
(On the left, there's only a sentence. And StatusBarItem
which shows the status of the program communicating will be added from the right.)
So i write the code like this.
StatusBarVieModel class
public class StatusBarViewModel : ViewModelBase
{
private string _alignment;
public string Alignment
{
get
{
return _alignment;
}
set
{
_alignment = value;
OnPropertyChanged(nameof(Alignment));
}
}
private ObservableCollection<BarItemViewModel> _barItems;
public ObservableCollection<BarItemViewModel> BarItems
{
get
{
return _barItems;
}
set
{
_barItems = value;
OnPropertyChanged(nameof(BarItems));
}
}
}
BarItemViewModel class
public class BarItemViewModel : ViewModelBase
{
private string _itemName;
public string ItemName
{
get
{
return _itemName;
}
set
{
_itemName = value;
OnPropertyChanged(nameof(ItemName));
}
}
private string _backgroundColor;
public string BackgroundColor
{
get
{
return _backgroundColor;
}
set
{
_backgroundColor = value;
OnPropertyChanged(nameof(BackgroundColor));
}
}
private string _foregroundColor;
public string ForegroundColor
{
get
{
return _foregroundColor;
}
set
{
_foregroundColor = value;
OnPropertyChanged(nameof(ForegroundColor));
}
}
MainWindowView.xaml
...
<StatusBar Grid.Row="2" DockPanel.Dock="Bottom" ItemsSource="{Binding StatusBars}" >
<StatusBar.ItemTemplate>
<DataTemplate DataType="{x:Type vms:BarItemViewModel}">
<StatusBarItem HorizontalAlignment="{Binding Alignment}">
<StackPanel Orientation="Horizontal">
<StatusBarItem Content="{Binding BarItems.ItemName}"/>
</StackPanel>
</StatusBarItem>
</DataTemplate>
</StatusBar.ItemTemplate>
</StatusBar>
MainWindowViewModel
public class MainWindowViewModel : ViewModelBase
{
public MainWindowViewModel()
{
CreateBarItems();
}
private ObservableCollection<StatusBarViewModel> _statusBars;
public ObservableCollection<StatusBarViewModel> StatusBars
{
get
{
return this._statusBars;
}
set
{
this._statusBars = value;
OnPropertyChanged("StatusBars");
}
}
private void CreateBarItems()
{
StatusBars = new ObservableCollection<StatusBarViewModel>
{
new StatusBarViewModel
{
Alignment = "Left",
BarItems = new ObservableCollection<BarItemViewModel>
{
new BarItemViewModel{ ItemName = "test1", BackgroundColor = "Black", ForegroundColor = "White"},
}
},
new StatusBarViewModel
{
Alignment = "Right",
BarItems = new ObservableCollection<BarItemViewModel>
{
new BarItemViewModel{ ItemName = "test2", BackgroundColor = "#52d976", ForegroundColor = "Black"},
new BarItemViewModel{ ItemName = "test3", BackgroundColor = "Red", ForegroundColor = "Black"},
}
},
};
}
}
But if i run this code, it gives me binding error with BarItems.ItemName
...
How can I add a StatusBarItem
dynamically as I want?
you need to use an ItemsControl to create multiple elements from BarItems collection:
<StatusBar Grid.Row="2" DockPanel.Dock="Bottom" ItemsSource="{Binding StatusBars}" >
<StatusBar.ItemTemplate>
<DataTemplate DataType="{x:Type vms:StatusBarViewModel}">
<StatusBarItem HorizontalAlignment="{Binding Alignment}">
<ItemsControl ItemsSource="{Binding BarItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type vms:BarItemViewModel}">
<StatusBarItem Content="{Binding ItemName}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StatusBarItem>
</DataTemplate>
</StatusBar.ItemTemplate>
</StatusBar>
also note that you had a wrong DataType on the first DataTemplate