ItemsControl with ItemSource set to ObservableCollection of UserControls fails to render in visual tree
inside TestEntryView.xaml.cs
public partial class TestEntryView : UserControl
{
public ObservableCollection<TestFieldView> Fields {get;set;}
...
}
where TestFieldView is a UserControl.
<UserControl x:Class="STS2Editor.View.TestEntryView"
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:vw="clr-namespace:STS2Editor.View"
mc:Ignorable="d"
x:Name="testEntryView"
d:DesignHeight="300"
d:DesignWidth="427"
d:DataContext="{Binding TestEntry, Source={StaticResource Sample}}"&开发者_JAVA百科gt;
<Grid Background="{DynamicResource ButtonNormalBorder}" TextElement.Foreground="{DynamicResource TextBrush}">
<Border Background="{DynamicResource ControlBackgroundBrush}" BorderBrush="{DynamicResource ControlBackgroundBrush}" BorderThickness="4" CornerRadius="16">
<Grid Margin="4" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ScrollViewer Background="{DynamicResource ControlBackgroundBrush}" Grid.IsSharedSizeScope="True" Grid.Row="1">
<ItemsControl x:Name="fieldList" ItemsSource="{Binding Fields, ElementName=testEntryView}"/>
</ScrollViewer>
</Grid>
</Border>
</Grid>
The binding is right, but when I snoop the visual tree my child items all consist of a border and content presenter, no child visuals.
I can only recreate your situation if for some reason LoadComponent is not called on your UserControl (TestFieldView) and the Xaml is not parsed correctly. This happens in InitializeComponent (see for example What does InitializeComponent() do, and how does it work in WPF?). Are you sure you call it in the contructor of the TestFieldView?
Are you sure this is the binding is connecting up to the correct data? I much prefer the
{Binding Fields,RelativeSource={RelativeSource TemplatedParent}}
binding approach from within a user control, but it should work either way (as long as you are sure its binding it shouldn't matter (perhaps depending on how you create an instance of your control)
You don't seem to have a style or DataTemplate associated with your TestFieldView item or anything? Plus since you are using a ItemsControl you probably need to define the ItemsPaneltemplate as well.
<ItemsControl Grid.Row="1" ItemsSource="{Binding Fields}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsSelected}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
Not sure without getting ahold of your code and messing around with it till it works but its proably something around the Items Control, panel template, data template side of things.
Though if I am completely misunderstanding you could try replacing the ItemsControl with a ListView (as this should at least show you a list of class names) which would give you some sort of display then you can work from there.
Is the "TestEntryView.Fields" property a DependencyProperty? Or does it at least raise a PropertyChanged event? It wasn't clear on the above example if it does. If it isn't a DP or doesn't raise the PropertyChanged event, try one or the other. That may be the solution.
EDIT:
To change it to a dependency property, do this:
public ObservableCollection<TestFieldView> Fields
{
get { return (ObservableCollection<TestFieldView>)GetValue(FieldsProperty); }
set { SetValue(FieldsProperty, value); }
}
public static readonly DependencyProperty FieldsProperty =
DependencyProperty.Register("Fields", typeof(ObservableCollection<TestFieldView>), typeof(MainWindow),
new UIPropertyMetadata(new ObservableCollection<TestFieldView>()));
精彩评论