|
Bubbling vs Tunneling[^]
Again, I'm trying to handle an event in the Window that was invoked in the nested child control. The event is defined as Bubbling, therefore it goes UP the UI stack
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I have solved similar things before with the use of an attached behavior so you use that to bind the command to a property in the VM
|
|
|
|
|
Thanks. Do you have an example of that?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
You will need to install the NuGet:
NuGet Gallery | Microsoft.Xaml.Behaviors.Wpf 1.1.39[^]
Then create a class like this one:
public class ButtonAttatchment:Behavior<Button>
{
protected override void OnAttached()
{
AssociatedObject.Click += AssociatedObject_Click;
}
protected override void OnDetaching()
{
AssociatedObject.Click -= AssociatedObject_Click;
}
private void AssociatedObject_Click(object sender, System.Windows.RoutedEventArgs e)
{
if (AssociatedObject != null)
{
((ButtonAttatchment)sender).IsSpinning = !((ButtonAttatchment)sender).IsSpinning;
}
}
public static readonly DependencyProperty IsSpinningProperty = DependencyProperty.Register("IsSpinning", typeof(bool),typeof(ButtonAttatchment), new UIPropertyMetadata(false));
public bool IsSpinning
{
get => (bool)GetValue(IsSpinningProperty);
set => SetValue(IsSpinningProperty, value);
}
}
This basically creates a code-behind implementation that you could use to fix complicated binding issues.
|
|
|
|
|
Thanks. I'll give it a shot
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
The XAML code is like this:
<Window x:Class="WPF_Tunneling_AttatchedBehavior.MainWindow"
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:behavior="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:WPF_Tunneling_AttatchedBehavior"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<Button Content="Test">
<behavior:Interaction.Behaviors>
<local:ButtonAttatchment x:Name="vm"/>
</behavior:Interaction.Behaviors>
</Button>
<TextBox Text="{Binding ElementName=vm,Path=IsSpinning}"></TextBox>
</StackPanel>
</Window>
And I made a slight mistake but Im sure you have figured it out by now:
private void AssociatedObject_Click(object sender, System.Windows.RoutedEventArgs e)
{
if (AssociatedObject != null)
{
IsSpinning = !IsSpinning;
}
}
|
|
|
|
|
Thanks for the code, but I'm not sure if this solves my issue.
jFirst, see this image[^]. Second, see this[^]. It's almost what I want.
There's got to be a way to do this. I put a demo in this repo[^]. See the MainWIndow's XAML.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Ok, I don't really see what you are getting at but it can be solved extremley easy:
<Grid PreviewMouseDown="Grid_PreviewMouseDown">
<ctrls:OuterControl Background="Tan"
Height="225"
Width="300">
And
private void Grid_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (e.OriginalSource != null)
{
}
}
|
|
|
|
|
Referring to the first pic with all the nested controls, I have this Routed even deep inside MyNewControl
public static readonly RoutedEvent ItemSelectedEvent =
EventManager.RegisterRoutedEvent("ItemSelected",
RoutingStrategy.Tunnel,
typeof(RoutedEventHandler),
typeof(NavigationPane));
public event RoutedEventHandler ItemSelected
{
add { AddHandler(ItemSelectedEvent, value); }
remove { RemoveHandler(ItemSelectedEvent, value); }
}
private void RaiseItemSelectedEvent()
{
vars args = new SelectedItemEventArgs(ItemSelectedEvent, SelectedItem);
RaiseEvent(args);
}
How do I catch this event in the window? What is the syntax? Using some kind of Preview_... is going to catch a LOT of events. Is there no way to subscribe directly to that event from the Window?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I've got a listbox with expanders[^] in it.
The problem is that expander's header content is not stretched. I've tried all kinds of things, but I can't seem to get it. Here's the XAML
<Expander Padding="{Binding Padding, RelativeSource={RelativeSource TemplatedParent}}"
Margin="{Binding Margin, RelativeSource={RelativeSource TemplatedParent}}"
BorderBrush="{Binding BorderBrush, RelativeSource={RelativeSource TemplatedParent}}"
BorderThickness="{Binding BorderThickness, RelativeSource={RelativeSource TemplatedParent}}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
IsExpanded="{Binding IsPaneExpanded, RelativeSource={RelativeSource TemplatedParent}}">
<Expander.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Header}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="1"/>
<Button Grid.Column="1"
Height="18"
Width="18"
Margin="0,1,1,1"/>
</Grid>
</Expander.Header>
<CONTENT REMOVED FOR BREVITY>
</Expander>
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Stretching Content in an Expander Header | Josh Smith on WPF[^]
The width binding trick won't work, as it will push the button outside of the available space. But the code-behind trick should be OK.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
That did it.
I saw this article already and tried the XAML approach. I should have hep reading.
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Does anyone have any good example code that demonstrates drag and drop for LISTBOX and TREEVIEWs?
I need this using VB.NET WPF in specific!
Thanks for the help!
|
|
|
|
|
|
|
I have a listbox bound to an entity called NavigationItemEntity which displays hyperlinks as the list items:
XAML
<ListBox x:Name="itemsList"
ItemsSource="{Binding Items, RelativeSource={RelativeSource TemplatedParent}}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
Margin="2"
BorderBrush="Transparent"
BorderThickness="0">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<local:MaroisHyperlink LinkText="{Binding Caption}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="LinkClicked">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type local:MaroisNavigationPane}},
Path=ItemClickedCommand}"
CommandParameter="{Binding Path=SelectedItem,ElementName=itemsList}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</local:MaroisHyperlink>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Code behind
private ICommand _ItemClickedCommand;
public ICommand ItemClickedCommand
{
get
{
if (_ItemClickedCommand == null)
_ItemClickedCommand = new RelayCommand<NavigationEntity>(p => ItemClickedExecuted(p), p => ItemClickedCanExecute(p));
return _ItemClickedCommand;
}
}
private bool ItemClickedCanExecute(NavigationEntity args)
{
return true;
}
private void ItemClickedExecuted(NavigationEntity args)
{
RaiseItemClickedEvent(args.Id, args.ItemType);
}
The problem is that if I first don't click the list item, but just the link, then the link is sent as the command parameter. If I first click the list item, THEN click the link, then entity is passed, which is what I want.
How can I force the list item to be selected when its link is clicked?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
When you click the link, it doesn't select the item first, so the SelectedItem won't be what you're expecting.
Try using:
CommandParameter="{Binding}"
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
That did it. Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I created this dummy control to ask the question... It's a TextBox with 2 buttons.
If I wanted to give this control in an assembly to another developer, how would they modify the style to fit their needs? You can see I have named my brushes with some care, but what about changing triggers or maybe animations and other things? If this is all inside an assembly, how does the developer know how the style works what the style does?
Generica.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyControl">
<SolidColorBrush x:Key="Button.Normal.Foreground" Color="SteelBlue"/>
<SolidColorBrush x:Key="Button.Normal.Background" Color="BlanchedAlmond"/>
<SolidColorBrush x:Key="Button.Normal.Border" Color="DarkGray"/>
<SolidColorBrush x:Key="Button.Hover.Background" Color="Orange"/>
<SolidColorBrush x:Key="Button.Hover.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="Button.Pressed.Foreground" Color="Salmon"/>
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FF737B7F"/>
<SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="DarkGray"/>
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
<SolidColorBrush x:Key="TextBlock.Normal.Foreground" Color="SteelBlue"/>
<SolidColorBrush x:Key="TextBlock.Normal.Background" Color="BlanchedAlmond"/>
<SolidColorBrush x:Key="TextBlock.Normal.Border" Color="DarkGray"/>
<SolidColorBrush x:Key="TextBlock.Hover.Background" Color="#FFBEE6FD"/>
<SolidColorBrush x:Key="TextBlock.Hover.Foreground" Color="Blue"/>
<SolidColorBrush x:Key="TextBlock.Hover.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="TextBlock.Pressed.Foreground" Color="Blue"/>
<SolidColorBrush x:Key="TextBlock.Pressed.Background" Color="#FF737B7F"/>
<SolidColorBrush x:Key="TextBlock.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="TextBlock.Disabled.Foreground" Color="DarkGray"/>
<SolidColorBrush x:Key="TextBlock.Disabled.Background" Color="#FFF4F4F4"/>
<SolidColorBrush x:Key="TextBox.Normal.Foreground" Color="SteelBlue"/>
<SolidColorBrush x:Key="TextBox.Normal.Background" Color="White"/>
<SolidColorBrush x:Key="TextBox.Normal.Border" Color="DarkGray"/>
<SolidColorBrush x:Key="TextBox.Hover.Background" Color="#FFBEE6FD"/>
<SolidColorBrush x:Key="TextBox.Hover.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="TextBox.Pressed.Background" Color="#FF737B7F"/>
<SolidColorBrush x:Key="TextBox.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="TextBox.Disabled.Foreground" Color="DarkGray"/>
<SolidColorBrush x:Key="TextBox.Disabled.Background" Color="#FFF4F4F4"/>
<Geometry x:Key="addButtonPathData">
M20 14H14V20H10V14H4V10H10V4H14V10H20V14Z
</Geometry>
<Geometry x:Key="removeButtonPathData">
M20 14H4V10H20V14Z
</Geometry>
<Style x:Key="pathImageButtonStyle"
TargetType="{x:Type local:PathImageButton}">
<Setter Property="Background" Value="{StaticResource Button.Normal.Background}"/>
<Setter Property="Height" Value="35"/>
<Setter Property="Width" Value="75"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:PathImageButton}">
<Grid x:Name="Grid">
<Border x:Name="border"
Margin="2"
Background="{StaticResource Button.Normal.Background}"
BorderBrush="DarkGray"
BorderThickness="1"
CornerRadius="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Path Grid.Column="0"
x:Name="path"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="{Binding PathData, RelativeSource={RelativeSource TemplatedParent}}"
Fill="{StaticResource Button.Normal.Foreground}"
Stretch="Uniform"
Margin="4"/>
<TextBlock Grid.Column="1"
x:Name="caption"
Text="{Binding Caption, RelativeSource={RelativeSource TemplatedParent}}"
Foreground="{StaticResource TextBlock.Normal.Foreground}"
Background="{StaticResource TextBlock.Normal.Background}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="0,2,2,2"/>
</Grid>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="path" Property="Fill" Value="{StaticResource Button.Normal.Foreground}" />
<Setter TargetName="caption" Property="Foreground" Value="{StaticResource TextBlock.Hover.Foreground}" />
<Setter TargetName="border" Property="Background" Value="{StaticResource Button.Hover.Background}" />
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource Button.Hover.Border}" />
<Setter TargetName="border" Property="BorderThickness" Value="1" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="path" Property="Fill" Value="{StaticResource Button.Pressed.Foreground}" />
<Setter TargetName="caption" Property="Foreground" Value="{StaticResource TextBlock.Pressed.Foreground}" />
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource Button.Pressed.Foreground}" />
<Setter TargetName="border" Property="BorderThickness" Value="1" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="path" Property="Fill" Value="{StaticResource Button.Disabled.Foreground}" />
<Setter TargetName="caption" Property="Foreground" Value="{StaticResource TextBlock.Disabled.Foreground}" />
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource Button.Disabled.Foreground}" />
<Setter TargetName="border" Property="BorderThickness" Value="0" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="buttonBaseStyle"
BasedOn="{StaticResource pathImageButtonStyle }"
TargetType="{x:Type local:PathImageButton}">
<Setter Property="Height" Value="32"/>
<Setter Property="Width" Value="100"/>
</Style>
<Style x:Key="addButtonStyle"
BasedOn="{StaticResource buttonBaseStyle }"
TargetType="{x:Type local:PathImageButton}">
<Setter Property="Caption" Value="Add"/>
<Setter Property="PathData" Value="{StaticResource addButtonPathData}"/>
</Style>
<Style x:Key="removeButtonStyle"
BasedOn="{StaticResource buttonBaseStyle }"
TargetType="{x:Type local:PathImageButton}">
<Setter Property="Caption" Value="Remove"/>
<Setter Property="PathData" Value="{StaticResource removeButtonPathData}"/>
</Style>
<Style TargetType="{x:Type local:CustomControl1}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomControl1}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Width="{Binding Width, RelativeSource={RelativeSource TemplatedParent}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height=""/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=""/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Row="0"
Grid.Column="0"
Orientation="Horizontal"
HorizontalAlignment="Stretch">
<TextBox Background="{StaticResource TextBox.Normal.Background}"
FontSize="18"
VerticalContentAlignment="Center"
Width="250"
Margin="2"/>
<local:PathImageButton Style="{StaticResource addButtonStyle}"/>
<local:PathImageButton Style="{StaticResource removeButtonStyle}"
IsEnabled="True"/>
</StackPanel>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Well, the easiest way to let people know is if you document the styles just the way you have here. If people want to adjust the triggers and templates, they can see what is affected just by reading the documentation.
|
|
|
|
|
I am working on this Navigation control[^].
See this earlier post[^] The code is in this repository[^].
What I'm trying to accomplish now is to have each Pane load individually only when expanded.
I added a Func that I want to use inside the pane to call the data
<pre>NavigationPaneInfos = new List<NavigationPaneModel>
{
new NavigationPaneModel
{
Header = "Projects",
NavigationItemType = NavigationItemType.Project,
IsExpanded = true,
DataSource = Repository.GetNavigationItems
},
new NavigationPaneModel
{
Header = "Inventory",
NavigationItemType = NavigationItemType.Inventory,
DataSource = Repository.GetNavigationItems
},
new NavigationPaneModel
{
Header = "Companies" ,
NavigationItemType = NavigationItemType.Company,
DataSource = Repository.GetNavigationItems
},
new NavigationPaneModel
{
Header = "Employees",
NavigationItemType = NavigationItemType.Employee,
DataSource = Repository.GetNavigationItems
}
};
Next I modified the outer container's loading
private void Load()
{
if (NavigationPanes != null)
{
ContainerItems = new List<NavigationPane>();
foreach (var navigationPaneModel in NavigationPanes)
{
var navigationPane = new NavigationPane
{
Header = navigationPaneModel.Header ?? "",
ItemType = navigationPaneModel.NavigationItemType,
NavigationPaneModel = navigationPaneModel
};
ContainerItems.Add(navigationPane);
navigationPane.IsExpanded = navigationPaneModel.IsExpanded;
}
}
}
Finally, I changed the pane loading to only happen when IsExpanded is changed:
public static readonly DependencyProperty IsExpandedProperty =
DependencyProperty.Register("IsExpanded",
typeof(bool),
typeof(NavigationPane),
new PropertyMetadata(false, new PropertyChangedCallback(OnIsExpandedChanged)));
public bool IsExpanded
{
get { return (bool)GetValue(IsExpandedProperty); }
set { SetValue(IsExpandedProperty, value); }
}
private static async void OnIsExpandedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (NavigationPane)d;
if (control.NavigationPaneModel != null)
{
await control.Load();
}
}
private async Task Load()
{
if (NavigationPaneModel != null && NavigationPaneModel.DataSource != null)
{
var dataSource = NavigationPaneModel.DataSource(NavigationPaneModel.NavigationItemType);
List<NavigationEntity>? data = null;
if (dataSource != null)
{
data = await Task.Run(() => dataSource);
}
if (data != null)
{
Items = new ObservableCollection<NavigationEntity>(data);
}
}
}
It's throwing a binding error when I invoke the func.
A 'Binding' cannot be set on the 'Header' property of type 'NavigationPane'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.'
Yet the Header property IS a DP.
I've been staring it this for hours. I would appreciate some help. Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
That's a nice simple one!
In NavigationPane.cs you have:
public static readonly DependencyProperty HeaderProperty =
DependencyProperty.Register("Header",
typeof(string),
typeof(NavigationContainer),
new PropertyMetadata("", new PropertyChangedCallback(OnHeaderChanged))); The ownerType needs to be typeof(NavigationPane) instead:
public static readonly DependencyProperty HeaderProperty =
DependencyProperty.Register("Header",
typeof(string),
typeof(NavigationPane),
new PropertyMetadata("", new PropertyChangedCallback(OnHeaderChanged)));
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
LOL. I stared at this forever.
I need a vacation
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
OK, so I'm close to done with this, but there's still a related problem.
In the MainWindow's code behind I have
NavigationPaneInfos = new List<NavigationPaneModel>
{
new NavigationPaneModel
{
Header = "Projects",
NavigationItemType = NavigationItemType.Project,
DataSource = Repository.GetNavigationItems,
IsExpanded = true
},
new NavigationPaneModel
{
Header = "Inventory",
NavigationItemType = NavigationItemType.Inventory,
DataSource = Repository.GetNavigationItems
},
new NavigationPaneModel
{
Header = "Companies" ,
NavigationItemType = NavigationItemType.Company,
DataSource = Repository.GetNavigationItems,
IsExpanded = true
},
new NavigationPaneModel
{
Header = "Employees",
NavigationItemType = NavigationItemType.Employee,
DataSource = Repository.GetNavigationItems
}
};
Here's the Pane's NavigationModel DP
public static readonly DependencyProperty NavigationPaneModelProperty =
DependencyProperty.Register("NavigationPaneModel",
typeof(NavigationPaneModel),
typeof(NavigationPane),
new PropertyMetadata(null, new PropertyChangedCallback(OnNavigationPaneModelChanged)));
public NavigationPaneModel NavigationPaneModel
{
get { return (NavigationPaneModel)GetValue(NavigationPaneModelProperty); }
set { SetValue(NavigationPaneModelProperty, value); }
}
private static async void OnNavigationPaneModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (NavigationPane)d;
if (control.NavigationPaneModel.IsExpanded)
{
control.IsPaneExpanded = true;
}
}
The IsPaneExpanded DP
public static readonly DependencyProperty IsPaneExpandedProperty =
DependencyProperty.Register("IsPaneExpanded",
typeof(bool),
typeof(NavigationPane),
new PropertyMetadata(false, new PropertyChangedCallback(OnIsPaneExpandedChanged)));
public bool IsPaneExpanded
{
get { return (bool)GetValue(IsPaneExpandedProperty); }
set { SetValue(IsPaneExpandedProperty, value); }
}
private static async void OnIsPaneExpandedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (NavigationPane)d;
if (control.IsPaneExpanded)
{
if (control.NavigationPaneModel != null)
{
await control.Load();
}
}
}
In addition, even though IsPaneExpanded is getting set to True, the pane never expands. I'm not getting any binding errors, and you can see the code behind is getting called.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
The problem is you have two instances of the NavigationPane for each expander - one that you create through code and add to the ContainerItems property, and one that's declared in XAML.
You don't have a binding for the NavigationPaneModel property in the XAML, so that property doesn't propagate from the ContainerItems instance to the XAML instance.
If you add a binding, then the property won't be null:
<ctrls:NavigationPane BorderBrush="Orange"
BorderThickness="3"
Background="Red"
NavigationPaneModel="{Binding NavigationPaneModel}"
Header="{Binding Header}"
Items="{Binding Items}"
Margin="0,0,0,1"/>
Alternatively, remove the ListBox.ItemTemplate so that the list displays the items created in code. You can use a style to set the additional properties:
<ListBox Grid.Row="1"
Margin="1"
BorderThickness="1"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding ContainerItems, RelativeSource={RelativeSource TemplatedParent}}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListBox.Resources>
<Style TargetType="ctrls:NavigationPane">
<Setter Property="BorderBrush" Value="Orange" />
<Setter Property="BorderThickness" Value="3" />
<Setter Property="Background" Value="Red" />
<Setter Property="Margin" Value="0,0,0,1" />
</Style>
</ListBox.Resources>
</ListBox>
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|