I have a usercontrol that looks like:
and the xaml code:
<UserControl x:Class="Customizing.Views.IpRangeView"
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:ig="http://schemas.infragistics.com/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:mvvm="http://www.galasoft.ch/mvvmlight"
xmlns:range="clr-namespace:Customizing.Views"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
DataContext="{Binding IpRangeVm, Source={StaticResource Locator}}">
<Grid>
<ig:ThemeManager.Theme>
<ig:Office2013Theme StyleMicrosoftControls="True" />
</ig:ThemeManager.Theme>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TabControl Grid.Row="0" ItemsSource="{Binding Locations}">
<TabControl.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Name}" FontSize="16" FontWeight="Bold" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Addresses}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="2" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Margin="20,15,20,15" Padding="15,20,15,20">
<range:IpRangeFields Start="{Binding Start}" End="{Binding End}"
Subnet="{Binding Subnet}" Gateway="{Binding Gateway}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Error">
<mvvm:EventToCommand Command="{Binding Path=DataContext.ErrorCmd, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</range:IpRangeFields>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
</UserControl>
As you can see on picture, only subnet field is filled with values, why the binding with, for example start, end and gateway does not work? What am I doing wrong
<range:IpRangeFields Start="{Binding Start}" End="{Binding End}"
Subnet="{Binding Subnet}" Gateway="{Binding Gateway}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Error">
<mvvm:EventToCommand Command="{Binding Path=DataContext.ErrorCmd, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</range:IpRangeFields>
And the view model and the view is bound to:
using System.Collections.ObjectModel;
using System.Diagnostics;
using Customizing.Models;
using Customizing.Services;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
namespace Customizing.ViewModel
{
public class IpRangeViewModel : ViewModelBase
{
private readonly IDataService _dataService;
public IpRangeViewModel(IDataService dataService)
{
_dataService = dataService;
_dataService.QueryIpRanges((ranges, error) => { Locations = ranges; });
ErrorCmd = new RelayCommand(() => { Debug.WriteLine("Error occurs"); });
}
public ObservableCollection<LocationRange> Locations { get; set; }
public RelayCommand ErrorCmd { get; set; }
}
}
and the model
using System.Collections.ObjectModel;
namespace Customizing.Models
{
public class LocationRange
{
public string Name { get; set; }
public ObservableCollection<IpRange> Addresses { get; set; }
}
}
Usercontrol iprangefield:
<UserControl x:Class="Customizing.Views.IpRangeFields"
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:ig="http://schemas.infragistics.com/xaml"
xmlns:local="clr-namespace:Customizing.Views"
xmlns:net="clr-namespace:System.Net;assembly=System"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:behaviors="clr-namespace:Customizing.Behaviors"
xmlns:system="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
x:Name="_parent"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<system:String x:Key="InputMaskIp">000.000.000.000</system:String>
</UserControl.Resources>
<Grid DataContext="{Binding ElementName=_parent}">
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition Height="10" />
<RowDefinition Height="60" />
<RowDefinition Height="10" />
<RowDefinition Height="60" />
<RowDefinition Height="10" />
<RowDefinition Height="60" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2.5*" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="Start" VerticalContentAlignment="Center" FontSize="18"
HorizontalContentAlignment="Center" FontWeight="Bold" />
<Label Grid.Row="2" Grid.Column="0" Content="End" VerticalContentAlignment="Center" FontSize="18"
HorizontalContentAlignment="Center" FontWeight="Bold" />
<Label Grid.Row="4" Grid.Column="0" Content="Subnet" VerticalContentAlignment="Center" FontSize="18"
HorizontalContentAlignment="Center" FontWeight="Bold" />
<Label Grid.Row="6" Grid.Column="0" Content="Gateway" VerticalContentAlignment="Center" FontSize="18"
HorizontalContentAlignment="Center" FontWeight="Bold" />
<TextBox VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Grid.Row="0" Grid.Column="1"
FontSize="22" Validation.Error="_ValidationError">
<Binding Path="Start" ValidatesOnNotifyDataErrors="True" UpdateSourceTrigger="PropertyChanged"
NotifyOnValidationError="true">
<Binding.ValidationRules>
<local:IpAddressRule />
</Binding.ValidationRules>
</Binding>
<i:Interaction.Behaviors>
<behaviors:TextBoxInputMaskBehavior InputMask="{StaticResource InputMaskIp}" PromptChar="0" />
</i:Interaction.Behaviors>
</TextBox>
<TextBox VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Grid.Row="2" Grid.Column="1"
FontSize="22" Validation.Error="_ValidationError">
<Binding Path="End" ValidatesOnNotifyDataErrors="True" UpdateSourceTrigger="PropertyChanged"
NotifyOnValidationError="true">
<Binding.ValidationRules>
<local:IpAddressRule />
</Binding.ValidationRules>
</Binding>
<i:Interaction.Behaviors>
<behaviors:TextBoxInputMaskBehavior InputMask="{StaticResource InputMaskIp}" PromptChar="0" />
</i:Interaction.Behaviors>
</TextBox>
<TextBox VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Grid.Row="4" Grid.Column="1"
FontSize="22" Validation.Error="_ValidationError">
<Binding Path="Subnet" ValidatesOnNotifyDataErrors="True" UpdateSourceTrigger="PropertyChanged"
NotifyOnValidationError="true">
<Binding.ValidationRules>
<local:IpAddressRule />
</Binding.ValidationRules>
</Binding>
<i:Interaction.Behaviors>
<behaviors:TextBoxInputMaskBehavior InputMask="{StaticResource InputMaskIp}" PromptChar="0" />
</i:Interaction.Behaviors>
</TextBox>
<TextBox VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Grid.Row="6" Grid.Column="1"
FontSize="22" Validation.Error="_ValidationError">
<Binding Path="Gateway" ValidatesOnNotifyDataErrors="True" UpdateSourceTrigger="PropertyChanged"
NotifyOnValidationError="true">
<Binding.ValidationRules>
<local:IpAddressRule />
</Binding.ValidationRules>
</Binding>
<i:Interaction.Behaviors>
<behaviors:TextBoxInputMaskBehavior InputMask="{StaticResource InputMaskIp}" PromptChar="0" />
</i:Interaction.Behaviors>
</TextBox>
</Grid>
</UserControl>
and the code behind:
using System;
using System.Diagnostics;
using System.Globalization;
using System.Net;
using System.Windows;
using System.Windows.Controls;
namespace Customizing.Views
{
/// <summary>
/// Interaction logic for IpRangeFields.xaml
/// </summary>
public partial class IpRangeFields : UserControl
{
public static readonly DependencyProperty StartProperty = DependencyProperty.Register("Start", typeof (string),
typeof (IpRangeFields), new PropertyMetadata(null));
public static readonly DependencyProperty EndProperty = DependencyProperty.Register("End", typeof (string),
typeof (IpRangeFields), new PropertyMetadata(null));
public static readonly DependencyProperty SubnetProperty = DependencyProperty.Register("Subnet", typeof (string),
typeof (IpRangeFields), new PropertyMetadata(null));
public static readonly DependencyProperty GatewayProperty = DependencyProperty.Register("Gateway",
typeof (string), typeof (IpRangeFields), new PropertyMetadata(null));
// Register the routed event
public static readonly RoutedEvent ErrorEvent =
EventManager.RegisterRoutedEvent("Error", RoutingStrategy.Bubble,
typeof(RoutedEventHandler), typeof(IpRangeFields));
public IpRangeFields()
{
InitializeComponent();
}
public event RoutedEventHandler Error
{
add { AddHandler(ErrorEvent, value); }
remove { RemoveHandler(ErrorEvent, value); }
}
public string Start
{
get { return (string) GetValue(StartProperty); }
set { SetValue(StartProperty, value); }
}
public string End
{
get { return (string) GetValue(EndProperty); }
set { SetValue(EndProperty, value); }
}
public string Subnet
{
get { return (string) GetValue(SubnetProperty); }
set { SetValue(SubnetProperty, value); }
}
public string Gateway
{
get { return (string) GetValue(GatewayProperty); }
set { SetValue(GatewayProperty, value); }
}
private void _ValidationError(object sender, ValidationErrorEventArgs e)
{
RaiseEvent(new RoutedEventArgs(ErrorEvent, sender));
}
}
public class IpAddressRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
IPAddress ip;
if (!IPAddress.TryParse(value.ToString(), out ip))
{
return new ValidationResult(false, "IP address is not valid.");
}
return new ValidationResult(true, null);
}
}
}