UserControl在wpf中使用父元素?

Posted

技术标签:

【中文标题】UserControl在wpf中使用父元素?【英文标题】:UserControl using parent elements in wpf? 【发布时间】:2012-04-29 08:35:49 【问题描述】:

当您在 wpf 中有一个用户控件时,它可以到达其父元素之外吗?例如,我的用户控件只是列出了一些通用的东西,这些东西保存在控件中,这些控件封装在主窗口的停靠面板中,但我在主窗口中有一个文本框和按钮,我想从控件中访问它们......这可能吗?

这将节省我很多时间,而不是更改整个窗口的内容并在每个用户控件中显示相同的文本框/按钮。如果有人有这方面的例子,将不胜感激。

【问题讨论】:

再看一遍 - 您是否尝试过使用 DataBinding 和祖先的 RelativeSource 访问父元素?如果是这样,这是一个很好的SO answer。如果这似乎不是一个好的解决方案,您可能需要发布一些代码来说明问题。干杯 【参考方案1】:

是的,这是可能的,这里是一些我用来从具有 DP 的 UserControls 组成演示文稿的代码。

我一点也不喜欢它,但它确实有效。我也认为这是一个很棒的主题,也许一些代码将有助于获得更好的答案!

干杯, 浆果

用户控件 XAML

<Button x:Name="btnAddNewItem" Style="StaticResource blueButtonStyle" >
    <StackPanel Orientation="Horizontal">
        <Image Source="resx:Resx ResxName=Core.Presentation.Resources.MasterDetail, Key=bullet_add" Stretch="Uniform" />
        <Label x:Name="tbItemName" Margin="5" Foreground="White" Padding="10, 0">_Add New [item]</Label>
    </StackPanel>
</Button>

后面的用户控制代码

public partial class AddNewItemButton : UserControl

    ...

    #region Item Name

    public static readonly DependencyProperty ItemNameProperty = DependencyProperty.Register(
        "ItemName", typeof(string), typeof(AddNewItemButton),
        new FrameworkPropertyMetadata(OnItemNameChanged));

    public string ItemName
    
        get  return (string)GetValue(ItemNameProperty); 
        set  SetValue(ItemNameProperty, value); 
    

    public string ButtonText  get  return (string) tbItemName.Content;  

    private static void OnItemNameChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    
        // When the item name changes, set the text of the item name
        var control = (AddNewItemButton)obj;

        control.tbItemName.Content = string.Format(GlobalCommandStrings.Subject_Add, control.ItemName.Capitalize());
        control.ToolTip = string.Format(GlobalCommandStrings.Subject_Add_ToolTip, control.ItemName);
    

    #endregion

    #region Command

    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
        "Command", typeof(ICommand), typeof(AddNewItemButton),
        new FrameworkPropertyMetadata(OnCommandChanged));

    public ICommand Command
    
        get  return (ICommand)GetValue(CommandProperty); 
        set  SetValue(CommandProperty, value); 
    

    private static void OnCommandChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    
        // When the item name changes, set the text of the item name
        var control = (AddNewItemButton)obj;
        control.btnAddNewItem.Command = control.Command;
    

    #endregion


另一个显示合成的用户控件

<UserControl ...
         xmlns:uc="clr-namespace:Smack.Core.Presentation.Wpf.Controls.UserControls" 
         >

    <DockPanel LastChildFill="True">
        ...
        <uc:AddNewItemButton x:Name="_addNewItemButton" Margin="0,0,10 0" DockPanel.Dock="Right"  />
        ...
    </DockPanel>
</UserControl>

【讨论】:

@KendallFrey。当您考虑它时,它并不是那么简单,但如果它适合您,只需发布​​一些简单明了的代码来说明您的情况。【参考方案2】:

回答您的问题:是的,您可以通过 RelativeSource 绑定或通过后面代码中的 Parent 成员访问父控件。但更好的答案类似于@KendallFrey 的答案。采用像 Light MVVM 这样的框架,并使用它的信使类或使用 Kendall 描述的事件。

【讨论】:

【参考方案3】:

更好的设计模式是让用户控件在需要更改某些内容时(通过事件)通知主窗口,并在需要某些信息时询问窗口(通过方法)。例如,您可以在用户控件可以调用的窗口上拥有一个 GetText() 方法,并在该窗口将订阅的用户控件上拥有一个 ChangeText 事件。

我们的想法是始终控制窗口。运用这种心态,将来开发应用程序会更容易。

【讨论】:

因此,如果您有一个文本框和按钮,那么使用您的示例,您将如何将文本发送到用户控件,然后在单击按钮时使用文本填充该控件? 在用户控件上创建一个方法(例如,SetText(string text))。在button1_Click,请致电myUserControl.SetText(myTextBox.Text)。在用户控件的SetText 方法中,你可以做任何你想做的事情来填充用户控件中的数据。

以上是关于UserControl在wpf中使用父元素?的主要内容,如果未能解决你的问题,请参考以下文章

wpf usercontrol,将按钮的命令参数绑定到父用户控件

在 UserControl WPF MVVM caliburn 内的 UserControl 之间切换

WPF怎么修改在窗体里引用的UserControl中元素的值?

wpf mvvm使用问题集锦

如何从UserControl访问父级的DataContext

[WPF]UserControl的MouseWheel事件触发