I'm working on a master detail page created by the Windows Template Studio. I'm trying to have a comboBox in the userControl that defines the DetailsTemplate, which loads its values from a list in the page.
Here's the code:
ArticlesPage.xaml
<Page
x:Class="Estimates.Views.ArticlesPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Style="{StaticResource PageStyle}"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:model="using:Estimates.Models"
xmlns:views="using:Estimates.Views"
xmlns:fcu ="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,5)"
xmlns:cu ="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractNotPresent(Windows.Foundation.UniversalApiContract,5)"
mc:Ignorable="d">
<Page.Transitions>
<TransitionCollection>
<NavigationThemeTransition />
</TransitionCollection>
</Page.Transitions>
<Page.Resources>
<DataTemplate x:Key="ItemTemplate" x:DataType="model:Article">
<Grid Height="64" Padding="0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" Margin="12,0,0,0" VerticalAlignment="Center">
<TextBlock Text="{x:Bind Description, Mode=TwoWay}" Style="{ThemeResource ListTitleStyle}"/>
</StackPanel>
</Grid>
</DataTemplate>
<DataTemplate x:Key="DetailsTemplate" x:DataType="views:ArticlesPage">
<views:ArticlesDetailControl MasterMenuItem="{Binding}" MeasureUnits="{x:Bind MeasureUnits}" />
</DataTemplate>
<DataTemplate x:Key="NoSelectionContentTemplate">
<TextBlock x:Uid="Articles_NoSelection" Style="{StaticResource ListNoSelectionTextStyle}" />
</DataTemplate>
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition x:Name="TitleRow" Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock
x:Uid="Articles_Title"
x:Name="TitlePage"
Margin="12,0,12,7"
Style="{StaticResource PageTitleStyle}" />
<controls:MasterDetailsView
Grid.Row="1"
x:Name="MasterDetailsViewControl"
ItemsSource="{x:Bind Items}"
SelectedItem="{x:Bind Selected, Mode=TwoWay}"
ItemTemplate="{StaticResource ItemTemplate}"
NoSelectionContentTemplate="{StaticResource NoSelectionContentTemplate}"
BorderBrush="Transparent"
DetailsTemplate="{StaticResource DetailsTemplate}" >
</controls:MasterDetailsView>
<Grid VerticalAlignment="Bottom" HorizontalAlignment="Right" Padding="0,15,0,0" Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button x:Uid="AddButton" Grid.Column="0" Margin="5" Click="AddButton"/>
<Button x:Uid="SaveButton" Grid.Column="1" Margin="5" Click="SaveButton"/>
<Button x:Uid="DeleteButton" Grid.Column="2" Margin="5" Click="DeleteButton"/>
</Grid>
<!-- Adaptive triggers -->
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="WindowStates">
<VisualState x:Name="WideState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="640"/>
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="NarrowState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="TitlePage.Margin" cu:Value="60,0,12,7" fcu:Value="12,0,12,7"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
ArticlesPage.xaml.cs
public sealed partial class ArticlesPage : Page, INotifyPropertyChanged
{
private Article _selected;
private ObservableCollection<MeasureUnit> _measureUnits;
private IRepositoryService _repositoryService { get; set; }
public Article Selected
{
get { return _selected; }
set { Set(ref _selected, value); }
}
public ObservableCollection<MeasureUnit> MeasureUnits
{
get { return _measureUnits; }
set { Set(ref _measureUnits, value);}
}
public ObservableCollection<Article> Items { get; private set; } = new ObservableCollection<Article>();
public ArticlesPage()
{
InitializeComponent();
Loaded += ArticlesPage_Loaded;
_repositoryService = new RepositoryService();
}
private void ArticlesPage_Loaded(object sender, RoutedEventArgs e)
{
Items.Clear();
ArticledDetailControl.xaml
<UserControl
x:Class="Estimates.Views.ArticlesDetailControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:Estimates.Models"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<ScrollViewer Name="ForegroundElement" VerticalScrollMode="Enabled" HorizontalAlignment="Stretch" Padding="12,0">
<StackPanel HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" Margin="0,8,0,0">
<TextBlock
Margin="12,0,0,0"
Text="{x:Bind MasterMenuItem.Description, Mode=TwoWay}"
Style="{StaticResource SubheaderTextBlockStyle}" />
</StackPanel>
<StackPanel Name="block" Padding="0,15,0,0">
<TextBox x:Uid="Description" Text="{x:Bind MasterMenuItem.Description, Mode=TwoWay}" />
<TextBox x:Uid="Notes" Text="{x:Bind MasterMenuItem.Notes, Mode=TwoWay}" Margin="0,6,0,0"/>
<Grid Margin="0,6,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.33*" />
<ColumnDefinition Width="0.33*" />
<ColumnDefinition Width="0.33*" />
</Grid.ColumnDefinitions>
<ComboBox x:Uid="MeasureUnits" x:Name="MeasureUnitsCB" ItemsSource="{x:Bind MeasureUnits}" Grid.Column="0">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="model:MeasureUnit">
<TextBlock Text="{x:Bind Description}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBox x:Uid="Price" Text="{x:Bind MasterMenuItem.Price, Mode=TwoWay}" Grid.Column="2" />
</Grid>
</StackPanel>
</StackPanel>
</ScrollViewer>
ArticlesDetailControl.xaml.cs
public sealed partial class ArticlesDetailControl : UserControl
{
public Article MasterMenuItem
{
get { return GetValue(MasterMenuItemProperty) as Article; }
set { SetValue(MasterMenuItemProperty, value); }
}
public IEnumerable<MeasureUnit> MeasureUnits
{
get { return GetValue(MeasureUnitsProperty) as IEnumerable<MeasureUnit>; }
set { SetValue(MeasureUnitsProperty, value); }
}
public static readonly DependencyProperty MasterMenuItemProperty =
DependencyProperty.Register("MasterMenuItem", typeof(Article), typeof(ArticlesDetailControl), new PropertyMetadata(null, OnMasterMenuItemPropertyChanged));
public static readonly DependencyProperty MeasureUnitsProperty =
DependencyProperty.Register("MeasureUnits", typeof(IEnumerable<MeasureUnit>), typeof(ArticlesDetailControl), new PropertyMetadata(null, OnMeasureUnitsPropertyChanged));
public ArticlesDetailControl()
{
InitializeComponent();
}
private static void OnMasterMenuItemPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as ArticlesDetailControl;
control.ForegroundElement.ChangeView(0, 0, 1);
}
private static void OnMeasureUnitsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Debug.WriteLine("PD");
}
}
So, the question is: How MasterMenuItem is populated? And why my property MeasureUnits it's not populated in the UserControl?
Edit: As suggested by TheZapper in the accepted answer, here's the implementation of OnMenuMasterItemPropertyChanged:
private static void OnMasterMenuItemPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as ArticlesDetailControl;
control.ForegroundElement.ChangeView(0, 0, 1);
if (control.MasterMenuItem.MeasureUnit != null)
{
control.MeasureUnitsCB.SelectedItem =
control.MeasureUnits.First(s => s.Id == control.MasterMenuItem.MeasureUnit.Id);
}
if (control.MasterMenuItem.VatCode != null)
{
control.VatCodesCB.SelectedItem =
control.VatCodes.First(s => s.Id == control.MasterMenuItem.VatCode.Id);
}
}
I load the lists in the constructor of the UserControl.
I guess your problem results from binding to MasterMenuItemProperty in your UserControl
Maybe you could add DependencyProperties as Notes, Description in your user control and define your Template like this
or you could try to update your bindings in the Changed-Event.