简体   繁体   English

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

[英]event fired on control added to the listbox

I want to know which event is fired when ListBoxItems are added to the ListBox. 我想知道将ListBoxItems添加到ListBox时会触发哪个事件。 Please take a note that I don't want an event when data changes. 请注意,我不希望在数据发生变化时发生事件。 I want the event when control is added. 我希望在添加控件时添加事件。

I have refered to this answer where they say use CollectionChaged Event It fires when Collection changes. 我已经提到了这个答案,他们说使用CollectionChaged Event它会在Collection更改时触发。 So I cannot use that as that fires before the controls are added to the VisualTree. 因此,在将控件添加到VisualTree之前,我无法使用它。

You might be thinking why I need that. 你可能在想我为什么需要那个。 I simply want to change the width of the listbox to the widest item's width. 我只想将列表框的宽度更改为最宽项目的宽度。 If you are interested more in what I am trying to achieve then please have a look at my code: 如果您对我想要实现的目标感兴趣,那么请查看我的代码:

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

Update: 更新:

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

as discussed here is how you can take control over most of the sizing aspects 这里讨论的是如何控制大多数尺寸方面

start by defining a new panel and override the method MeasureOverride 首先定义一个新面板并覆盖方法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 method will be invoked whenever any item is added or removed or a change in layout is required ie resizing the container. 无论何时添加或删除任何项目或需要更改布局(即调整容器大小),都将调用MeasureOverride方法。

foreach (ListBoxItem item in this.Children) is with assumption that you are going to use with ListBox only. foreach (ListBoxItem item in this.Children)假设您将仅使用ListBox。 You may change the same as desired. 您可以根据需要更改相同的内容。

then use this new panel as 然后使用这个新面板作为

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

with this approach you can control the sizing much efficiently 使用这种方法,您可以非常有效地控制尺寸

read more on FrameworkElement.MeasureOverride 阅读有关FrameworkElement.MeasureOverride的更多信息


after looking at the sample here are the changes you need to do to get the desired 在查看此处的示例之后,您需要进行更改以获得所需的更改

  • set the Margin="10,5,10,5" to sidebar ListBox Margin="10,5,10,5"为侧边栏ListBox

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

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

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

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

You can listen to Items CollectionChanged like 您可以收听Items 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)
            {

            }
        }
    }

Plus here you will get the items directly instead of using VisualTreeHelper 另外,您将直接获取项目,而不是使用VisualTreeHelper

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM