UserControl с использованием родительских элементов в wpf?

когда у вас есть usercontrol в wpf, может ли он выйти за пределы своих родительских элементов? Например, мой пользовательский элемент управления просто перечисляет некоторые общие вещи, которые хранятся внутри элемента управления, который инкапсулирован в dockpanel в главном окне, но у меня есть текстовое поле и кнопка в главном окне, к которым я хотел бы получить доступ из элемента управления... возможно ли это?

это сэкономило бы мне много времени, а не изменение содержимого всего окна и отображение того же самого текстовое поле / кнопка в каждом usercontrol. Если у кого есть пример этого он будет высоко ценится.

3 ответов


Да, это возможно, и вот некоторый код, который я использовал для создания презентаций из UserControls, которые имеют DPs.

Я не люблю его, хоть немного, но работает. Я также думаю, что это большой тема и, возможно, какой-то код поможет получить лучшие ответы!

спасибо,
Берри!--4-->

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

Код UserControl За

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

}

enter image description here

другой UserControl, показывающий состав

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

enter image description here


лучшим шаблоном дизайна было бы уведомить usercontrol (через событие) главное окно, когда что-то нужно изменить, и спросить окно (через метод), когда ему нужна некоторая информация. Например, у вас будет метод GetText() в окне, которое может вызвать usercontrol, и событие ChangeText в usercontrol, на которое будет подписываться окно.

идея состоит в том, чтобы держать окно под контролем во все времена. Использование этого менталитета облегчит вы будете разрабатывать приложения в будущем.


чтобы ответить на ваш вопрос: Да, вы можете получить доступ к родительским элементам управления либо через привязку RelativeSource, либо через родительский элемент в коде back. Но лучший ответ похож на ответ @KendallFrey. Принять рамки, как свет MVVM и использовать его класс messenger или использовать события так, как описал Кендалл.