列表框项目源作为用户控件

时间:2015-02-07 05:35:33

标签: c# wpf binding user-controls listbox

我有一个控件很少的用户控件。

<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>

我在ItemSource

中使用这组用户控件作为我的ListBox
<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; }
    }
}

然而Initializecomponent的{​​{1}}被调用两次

我绑定正确的方式吗?

我该怎么办?

由于

1 个答案:

答案 0 :(得分:1)

发生这种情况是因为,您通过调用相同的默认构造函数在控件列表中添加MyUserControl
此外,由于您在列表框MyUserControl中使用了DataTemplate,因此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()

因此,要解决您的问题,您可以为它解决问题,

  

创建参数化构造函数以添加控件 -

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)));