【问题标题】:WPF - Remove a "User Control" Child from a StackPanelWPF - 从 StackPanel 中删除“用户控件”子项
【发布时间】:2017-08-15 13:10:29
【问题描述】:

我正在尝试制作一个 WPF UI,用户可以在其中编辑查询以搜索数据库。查询是根据消费者从组合框Like This 中选择的内容创建的,只要单击添加新条件按钮,他就可以创建任意数量的过滤器。

我将组合框模板创建为这样的用户控件:

用户控制 XAML:

<StackPanel Orientation="Horizontal" >
        <Button
                Name="DeleteFilter" 
                HorizontalAlignment="Left"
                Margin="5"
                Content="-"
            Click="DeleteFilter_OnClick">
        </Button>
        <ComboBox 
                Text="Property"
                x:Name="Property"
                Width="100"
                DataContext="{StaticResource SomeViewModel}"
                ItemsSource="{Binding Properties}"
                DisplayMemberPath="Name"
             SelectionChanged="Property_OnSelectionChanged"/>
        <ComboBox 
            Text="PropertyOperator"
            x:Name="Operator"
            ItemsSource="{Binding Operators}"
            DisplayMemberPath="Name"
            SelectionChanged="Operator_OnSelectionChanged">
        </ComboBox>
        <TextBox 
                x:Name="Value"
                Text="Value"
                TextAlignment="Center"
                Width="100"
                Margin="5"/>
</StackPanel>

每当用户单击添加新条件按钮时,我都会调用此事件:

private void AddFilterButton_OnClick(object sender, RoutedEventArgs e)
    {
        var conditionUserControl = new ConditionUserControl();
        StackPanel.Children.Add(conditionUserControl);
    }

一切正常。

我的问题:

如何通过单击 DeleteFilter button that exists in the User Control template 删除用户控制子项。

我试过这个:

StackPanel.Children.Remove(..);

从我的 MainWindow 中删除孩子,但如何知道用户点击了哪个孩子。

【问题讨论】:

  • 按钮如何知道要删除哪个子项? StackPanel 不会为您提供SelectedItem.. 除非您为每个孩子添加按钮或以某种方式自己处理选择.. 您只是想remove last one
  • 不,我想删除用户点击的任何孩子,这可能吗?这才是重点。我是 WPF 新手,我不知道如何使这成为可能...您认为将按钮添加到每个创建的孩子是一个好主意吗?
  • “将按钮添加到每个创建的孩子” - 完全没问题。我没有注意到你已经这样做了。您可以在可视化树中找到包含按钮的用户控件,然后从 StackPanel 中删除该实例。
  • 您可以发布您的解决方案作为答案,而不是更改问题。在 lambda 中使用捕获的实例是明智之举。
  • 感谢您的建议。会做的!

标签: c# wpf xaml


【解决方案1】:

试试这个:

private void DeleteFilter_OnClick(object sender, RoutedEventArgs e)
{
    Button btn = sender as Button;
    var conditionUserControl = FindParent<ConditionUserControl>(btn);
    if (conditionUserControl != null)
    {
        var sp = FindParent<StackPanel>(conditionUserControl);
        if (sp != null)
            sp.Children.Remove(conditionUserControl);
    }
}


private static T FindParent<T>(DependencyObject dependencyObject) where T : DependencyObject
{
    var parent = VisualTreeHelper.GetParent(dependencyObject);

    if (parent == null) return null;

    var parentT = parent as T;
    return parentT ?? FindParent<T>(parent);
}

【讨论】:

  • 我无法理解答案。 AddFilterButton 应该将孩子添加到堆栈面板。实施您建议删除此功能.. 我是 WPF 的新手,如果我听起来不便,请道歉。
  • 抱歉,这是 DeleteFilter_OnClick 事件处理程序的实现。我改了名字。
  • 我明白了。 AddFilter 是 FilterWindow 类中的一个按钮,而 DeleteFilter 按钮在另一个名为 ConditionUserControl 的类中。因此,StackPanel 无法识别。
  • 那么你需要获取对 StackPanel 的引用。您可以以相同的方式执行此操作,即在可视化树中找到它,前提是 UC 是 SP 的子级。请参阅我编辑的答案。
【解决方案2】:

@mm8 的另一个答案是:

更新 AddFilterButton_OnClick:

我做了这个并且功能有效:

private void AddAndFilterButton_OnClick(object sender, RoutedEventArgs e)
    {
        var conditionUserControl = new ConditionUserControl();

        StackPanel.Children.Add(conditionUserControl);

        conditionUserControl.DeleteFilter.Click += (o, args) => StackPanel.Children.Remove(conditionUserControl);
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-01
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多