在控件上触发的事件已添加到列表框中

时间:2014-08-24 03:00:51

标签: c# wpf

我想知道将ListBoxItems添加到ListBox时会触发哪个事件。请注意,当数据发生变化时,我不希望发生任何事件。我希望在添加控件时发生事件。

我已经提到了这个答案,他们说使用CollectionChaged Event它会在Collection更改时触发。因此,在将控件添加到VisualTree之前,我无法使用它。

你可能在想我为什么需要那个。我只想将列表框的宽度更改为最宽的项目宽度。如果您对我想要实现的目标更感兴趣,那么请查看我的代码:

private void SomeEvent(object sender, ............... e)
{
    double greatestWidth = 0;

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(sidebar) - 1; i++)
    {
        ListBoxItem li = VisualTreeHelper.GetChild(sidebar, i) as ListBoxItem;
        li.HorizontalAlignment = HorizontalAlignment.Center;
    }

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(sidebar) - 1; i++)
    {
        ListBoxItem li = VisualTreeHelper.GetChild(sidebar, i) as ListBoxItem;
        if (li.Width > greatestWidth)
        {
            greatestWidth = li.Width;
        }
    }

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(sidebar) - 1; i++)
    {
        ListBoxItem li = VisualTreeHelper.GetChild(sidebar, i) as ListBoxItem;
        li.HorizontalAlignment = HorizontalAlignment.Stretch;
    }
}

更新

class ResizablePanel : StackPanel
{
    protected override Size MeasureOverride(Size constraint)
    {
        Size calculatedSize = base.MeasureOverride(constraint);

        foreach (ListBoxItem li in this.Children)
        {
            li.HorizontalAlignment = HorizontalAlignment.Center;
        }

        double greatestWidth = 0;

        foreach (ListBoxItem li in this.Children)
        {
            if (li.Width > greatestWidth)
            {
                greatestWidth = li.Width;
            }
        }

        foreach (ListBoxItem li in this.Children)
        {
            li.HorizontalAlignment = HorizontalAlignment.Stretch;
        }

        calculatedSize = new Size(greatestWidth, calculatedSize.Height);

        return calculatedSize;
    }
}

2 个答案:

答案 0 :(得分:3)

这里讨论的是如何控制大部分尺寸方面

首先定义一个新面板并覆盖方法MeasureOverride

namespace CSharpWPF
{
    class MyPanel : StackPanel
    {
        protected override Size MeasureOverride(Size constraint)
        {
            Size calculatedSize = base.MeasureOverride(constraint);
            foreach (ListBoxItem item in this.Children)
            {
                //your logic with each item
            }
            return calculatedSize;
        }
    }
}
每当添加或删除任何项目或者需要更改布局时,都会调用MeasureOverride方法,即调整容器大小。

foreach (ListBoxItem item in this.Children)假设您将仅使用ListBox。您可以根据需要更改相同的内容。

然后将此新面板用作

<ListBox xmlns:l="clr-namespace:CSharpWPF">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <l:MyPanel />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

通过这种方法,您可以更有效地控制尺寸

详情请阅读FrameworkElement.MeasureOverride


在查看此处的示例后,您需要进行更改才能获得所需的

  • Margin="10,5,10,5"设置为侧边栏ListBox

  • HorizontalAlignment="Right"添加到侧边栏ListBox

  • 从metro.xaml第35行的ContentPresenter中删除HorizontalAlignment="Center"

  • 设置<Setter Property="HorizontalAlignment" Value="Stretch" /> metro.xaml第51行

  • 在第52行添加<Setter Property="TextBlock.TextAlignment" Value="Right" />

答案 1 :(得分:0)

您可以收听项目CollectionChanged,如

        public Window1()
    {
        InitializeComponent();
        ((INotifyCollectionChanged)mylistbox.Items).CollectionChanged += myListBox_CollectionChanged;
    }

        private void myListBox_CollectionChanged(object sender,NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            foreach (var item in e.NewItems)
            {

            }
        }
    }

此外,您将直接获取项目,而不是使用VisualTreeHelper