列表框项目源作为用户控件
Listbox itemsource as User control
我有一个几乎没有控件的用户控件。
<UserControl>
<Grid>
<Expander Header="{Binding Path=Headerval}">
<StackPanel Margin="10,4,0,0">
<DataGrid
x:Name="dataGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding Path=records}"/>
</StackPanel>
</Expander>
</Grid>
</UserControl>
我在 ListBox
中使用这组用户控件作为我的 ItemSource
<ListBox x:Name="myListBox" ItemsSource="{Binding Path=_myControl}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<NewWPFApp:MyUserControl />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
在我的主窗口代码中
public ObservableCollection<GetControlsList> _myControl { get; set; }
_myControl = new ObservableCollection<GetControlsList>();
_myControl.Add(new GetControlsList(new MyUserControl()));
public class GetControlsList
{
public ObservableCollection<MyUserControl> _ListControls = new ObservableCollection<MyUserControl>();
public GetControlsList(params MyUserControl[] controls)
{
foreach (var control in controls)
{
_ListControls.Add(control);
}
}
public ObservableCollection<MyUserControl> ListCOntrols
{
get { return _ListControls; }
}
}
然而这里 MyUserControl
的 Initializecomponent
被调用了两次
我绑定的方式正确吗??
我该怎么办??
谢谢
发生这种情况是因为您通过调用相同的默认构造函数在 controlList 中添加 MyUserControl
。
此外,由于您在列表框 DataTemplate
中使用了 MyUserControl
,WPF 渲染器使用 MyUserControl
默认构造函数来添加其实例。这是 stackTrace - 它是如何与 ListBox
绑定的
at System.DefaultBinder.BindToMethod(BindingFlags bindingAttr, MethodBase[] match, Object[]& args, ParameterModifier[] modifiers, CultureInfo cultureInfo, String[] names, Object& state)
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateInstance(XamlType xamlType, Object[] args)
at MS.Internal.Xaml.Runtime.PartialTrustTolerantRuntime.CreateInstance(XamlType xamlType, Object[] args)
at System.Xaml.XamlObjectWriter.Logic_CreateAndAssignToParentStart(ObjectWriterContext ctx)
at System.Xaml.XamlObjectWriter.WriteEndObject()
at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlReader templateReader, XamlObjectWriter currentWriter)
at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlObjectWriter objectWriter)
at System.Windows.FrameworkTemplate.LoadOptimizedTemplateContent(DependencyObject container, IComponentConnector componentConnector, IStyleConnector styleConnector, List`1 affectedChildren, UncommonField`1 templatedNonFeChildrenField)
at System.Windows.FrameworkTemplate.LoadContent(DependencyObject container, List`1 affectedChildren)
at System.Windows.StyleHelper.ApplyTemplateContent(UncommonField`1 dataField, DependencyObject container, FrameworkElementFactory templateRoot, Int32 lastChildIndex, HybridDictionary childIndexFromChildID, FrameworkTemplate frameworkTemplate)
at System.Windows.FrameworkTemplate.ApplyTemplateContent(UncommonField`1 templateDataField, FrameworkElement container)
at System.Windows.FrameworkElement.ApplyTemplate()
at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
at System.Windows.UIElement.Measure(Size availableSize)
.
.
at System.Windows.UIElement.Measure(Size availableSize)
at System.Windows.Controls.VirtualizingStackPanel.MeasureChild(IItemContainerGenerator& generator, IContainItemStorage& itemStorageProvider, IContainItemStorage& parentItemStorageProvider, Object& parentItem, Boolean& hasUniformOrAverageContainerSizeBeenSet, Double& computedUniformOrAverageContainerSize, Boolean& computedAreContainersUniformlySized, IList& items, Object& item, IList& children, Int32& childIndex, Boolean& visualOrderChanged, Boolean& isHorizontal, Size& childConstraint, Rect& viewport, VirtualizationCacheLength& cacheSize, VirtualizationCacheLengthUnit& cacheUnit, Boolean& foundFirstItemInViewport, Double& firstItemInViewportOffset, Size& stackPixelSize, Size& stackPixelSizeInViewport, Size& stackPixelSizeInCacheBeforeViewport, Size& stackPixelSizeInCacheAfterViewport, Size& stackLogicalSize, Size& stackLogicalSizeInViewport, Size& stackLogicalSizeInCacheBeforeViewport, Size& stackLogicalSizeInCacheAfterViewport, Boolean& mustDisableVirtualization, Boolean isBeforeFirstItem, Boolean isAfterFirstItem, Boolean isAfterLastItem, Boolean skipActualMeasure, Boolean skipGeneration, Boolean& hasBringIntoViewContainerBeenMeasured, Boolean& hasVirtualizingChildren)
at System.Windows.Controls.VirtualizingStackPanel.MeasureOverrideImpl(Size constraint, Nullable`1& lastPageSafeOffset, List`1& previouslyMeasuredOffsets, Boolean remeasure)
at System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(Size constraint)
at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
.
.
.
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
所以要解决您的问题,您可以解决它,
Create a parameterised constructor to add your control-
public partial class MyUserControl : UserControl
{
public MyUserControl()
{
InitializeComponent();
}
// Use this when you are adding the control in the collection
public MyUserControl(int temp)
{
// Don't Call MyUserControl but do your other works here.
}
}
然后像这样添加-
_myControl = new ObservableCollection<GetControlsList>();
// remember here, you are calling MyUserControl(5), where 5 is just a temporary parameter, or you can also pass any useful parameter.
_myControl.Add(new GetControlsList(new MyUserControl(5)));
我有一个几乎没有控件的用户控件。
<UserControl>
<Grid>
<Expander Header="{Binding Path=Headerval}">
<StackPanel Margin="10,4,0,0">
<DataGrid
x:Name="dataGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding Path=records}"/>
</StackPanel>
</Expander>
</Grid>
</UserControl>
我在 ListBox
ItemSource
<ListBox x:Name="myListBox" ItemsSource="{Binding Path=_myControl}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<NewWPFApp:MyUserControl />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
在我的主窗口代码中
public ObservableCollection<GetControlsList> _myControl { get; set; }
_myControl = new ObservableCollection<GetControlsList>();
_myControl.Add(new GetControlsList(new MyUserControl()));
public class GetControlsList
{
public ObservableCollection<MyUserControl> _ListControls = new ObservableCollection<MyUserControl>();
public GetControlsList(params MyUserControl[] controls)
{
foreach (var control in controls)
{
_ListControls.Add(control);
}
}
public ObservableCollection<MyUserControl> ListCOntrols
{
get { return _ListControls; }
}
}
然而这里 MyUserControl
的 Initializecomponent
被调用了两次
我绑定的方式正确吗??
我该怎么办??
谢谢
发生这种情况是因为您通过调用相同的默认构造函数在 controlList 中添加 MyUserControl
。
此外,由于您在列表框 DataTemplate
中使用了 MyUserControl
,WPF 渲染器使用 MyUserControl
默认构造函数来添加其实例。这是 stackTrace - 它是如何与 ListBox
at System.DefaultBinder.BindToMethod(BindingFlags bindingAttr, MethodBase[] match, Object[]& args, ParameterModifier[] modifiers, CultureInfo cultureInfo, String[] names, Object& state)
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateInstance(XamlType xamlType, Object[] args)
at MS.Internal.Xaml.Runtime.PartialTrustTolerantRuntime.CreateInstance(XamlType xamlType, Object[] args)
at System.Xaml.XamlObjectWriter.Logic_CreateAndAssignToParentStart(ObjectWriterContext ctx)
at System.Xaml.XamlObjectWriter.WriteEndObject()
at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlReader templateReader, XamlObjectWriter currentWriter)
at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlObjectWriter objectWriter)
at System.Windows.FrameworkTemplate.LoadOptimizedTemplateContent(DependencyObject container, IComponentConnector componentConnector, IStyleConnector styleConnector, List`1 affectedChildren, UncommonField`1 templatedNonFeChildrenField)
at System.Windows.FrameworkTemplate.LoadContent(DependencyObject container, List`1 affectedChildren)
at System.Windows.StyleHelper.ApplyTemplateContent(UncommonField`1 dataField, DependencyObject container, FrameworkElementFactory templateRoot, Int32 lastChildIndex, HybridDictionary childIndexFromChildID, FrameworkTemplate frameworkTemplate)
at System.Windows.FrameworkTemplate.ApplyTemplateContent(UncommonField`1 templateDataField, FrameworkElement container)
at System.Windows.FrameworkElement.ApplyTemplate()
at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
at System.Windows.UIElement.Measure(Size availableSize)
.
.
at System.Windows.UIElement.Measure(Size availableSize)
at System.Windows.Controls.VirtualizingStackPanel.MeasureChild(IItemContainerGenerator& generator, IContainItemStorage& itemStorageProvider, IContainItemStorage& parentItemStorageProvider, Object& parentItem, Boolean& hasUniformOrAverageContainerSizeBeenSet, Double& computedUniformOrAverageContainerSize, Boolean& computedAreContainersUniformlySized, IList& items, Object& item, IList& children, Int32& childIndex, Boolean& visualOrderChanged, Boolean& isHorizontal, Size& childConstraint, Rect& viewport, VirtualizationCacheLength& cacheSize, VirtualizationCacheLengthUnit& cacheUnit, Boolean& foundFirstItemInViewport, Double& firstItemInViewportOffset, Size& stackPixelSize, Size& stackPixelSizeInViewport, Size& stackPixelSizeInCacheBeforeViewport, Size& stackPixelSizeInCacheAfterViewport, Size& stackLogicalSize, Size& stackLogicalSizeInViewport, Size& stackLogicalSizeInCacheBeforeViewport, Size& stackLogicalSizeInCacheAfterViewport, Boolean& mustDisableVirtualization, Boolean isBeforeFirstItem, Boolean isAfterFirstItem, Boolean isAfterLastItem, Boolean skipActualMeasure, Boolean skipGeneration, Boolean& hasBringIntoViewContainerBeenMeasured, Boolean& hasVirtualizingChildren)
at System.Windows.Controls.VirtualizingStackPanel.MeasureOverrideImpl(Size constraint, Nullable`1& lastPageSafeOffset, List`1& previouslyMeasuredOffsets, Boolean remeasure)
at System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(Size constraint)
at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
.
.
.
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
所以要解决您的问题,您可以解决它,
Create a parameterised constructor to add your control-
public partial class MyUserControl : UserControl
{
public MyUserControl()
{
InitializeComponent();
}
// Use this when you are adding the control in the collection
public MyUserControl(int temp)
{
// Don't Call MyUserControl but do your other works here.
}
}
然后像这样添加-
_myControl = new ObservableCollection<GetControlsList>();
// remember here, you are calling MyUserControl(5), where 5 is just a temporary parameter, or you can also pass any useful parameter.
_myControl.Add(new GetControlsList(new MyUserControl(5)));