I'm trying to bind a bunch of user controls to a WPF application. The idea is the viewmodel holds the list of server names, passes those to an ObservableCollection, and then the collection is bound to the main window.
When in design mode, everything works just fine! However, when I run the application, the binding seems to break down, and I'm at a loss to explain why.
This is the XAML for the user control:
<UserControl x:Class="ServerMonitor.Wpf.ServerControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ServerMonitor.Wpf"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.DataContext>
<local:Server />
</UserControl.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
</Style>
</Grid.Resources>
<TextBlock Grid.Row="0" Text="{Binding Name}" />
<TextBlock Grid.Row="8" Text="{Binding LastPolled}" />
</Grid>
</UserControl>
This is the view model (ViewModelBase is an abstract class that implements INotifyPropertyChanged):
public class MainWindowViewModel : ViewModelBase {
private List<string> _MachineNames = new List<string> {
"wschampad",
// Test
"T009", "T010", "T011", "T012",
};
public List<string> MachineNames {
get { return _MachineNames; }
set { _MachineNames = value; OnPropertyChanged("ManchineNames"); }
}
private ObservableCollection<Server> _Servers;
public ObservableCollection<Server> Servers {
get {
if (_Servers == null) {
_Servers = new ObservableCollection<Server>();
foreach (var machine in MachineNames) {
_Servers.Add(new Server {
Name = machine,
LastPolled = DateTime.Now,
});
}
OnPropertyChanged("Servers");
}
return _Servers;
}
set { _Servers = value; OnPropertyChanged("Servers"); }
}
}
And this is the main window XAML:
<Window x:Class="ServerMonitor.Wpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ServerMonitor.Wpf"
Title="Leading Hedge Server Monitor" Height="350" Width="800">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Menu Grid.Row="0">
<MenuItem Header="_File">
<MenuItem Header="_Exit" Name="MenuFileExit" Click="MenuFileExit_Click" />
</MenuItem>
<MenuItem Header="_Edit">
<MenuItem Header="_Options" Name="MenuEditOptions" IsEnabled="False" />
</MenuItem>
<MenuItem Header="_Help">
<MenuItem Header="_About" Name="MenuHelpAbout" IsEnabled="False" />
</MenuItem>
</Menu>
<ItemsControl Grid.Row="1" ItemsSource="{Binding Servers}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="1" Margin="5,5,5,5">
<local:ServerControl DataContext="{Binding}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
EDIT
Changing the DataContext within the UserControl to ignorable worked to correct the issue!
<UserControl x:Class="ServerMonitor.Wpf.ServerControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ServerMonitor.Wpf"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<d:UserControl.DataContext>
<local:Server />
</d:UserControl.DataContext>
