如何在设计中设置用户控件的自定义依赖项属性 [英] How to set a custom dependency property of user control in design

查看:91
本文介绍了如何在设计中设置用户控件的自定义依赖项属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我有一个包含以下usercontrol的UserControl库:DisplayGrid

XAML:

Hello everyone,
I have a UserControl library containing the following usercontrol : DisplayGrid
XAML :

<UserControl x:Class="KelanicControls.DisplayGrid"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

             xmlns:local="clr-namespace:KelanicControls"

             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

             x:Name="uc"

             d:DesignHeight="300"

             d:DesignWidth="300"

             Loaded="uc_Loaded"

             mc:Ignorable="d">

    <Grid x:Name="mainGrid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="1*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="1*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="1*" />
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0"

                    Grid.ColumnSpan="3"

                    removed="{Binding ElementName=uc,
                                         Path=GridBackground}"

                    MouseLeftButtonUp="StackPanel_MouseLeftButtonUp"

                    Opacity="0.85" />
        <StackPanel Grid.Row="1"

                    removed="{Binding ElementName=uc,
                                         Path=GridBackground}"

                    MouseLeftButtonUp="StackPanel_MouseLeftButtonUp"

                    Opacity="0.85" />

        <Border x:Name="borderChildContainer"

                Grid.Row="1"

                Grid.Column="1" />

        <StackPanel Grid.Row="1"

                    Grid.Column="2"

                    removed="{Binding ElementName=uc,
                                         Path=GridBackground}"

                    MouseLeftButtonUp="StackPanel_MouseLeftButtonUp"

                    Opacity="0.85" />
        <StackPanel Grid.Row="2"

                    Grid.ColumnSpan="3"

                    removed="{Binding ElementName=uc,
                                         Path=GridBackground}"

                    MouseLeftButtonUp="StackPanel_MouseLeftButtonUp"

                    Opacity="0.85" />
    </Grid>
</UserControl>



代码:


Code :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace KelanicControls
{
    /// <summary>
    /// Interaction logic for DisplayGrid.xaml
    /// </summary>
    public partial class DisplayGrid : UserControl 
    {
        public DisplayGrid()
        {
            InitializeComponent();
        }
        public Brush GridBackground
        {
            get { return (Brush)GetValue(GridBackgroundProperty); }
            set { SetValue(GridBackgroundProperty, value); }
        }

        // Using a DependencyProperty as the backing store for GridBackground.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty GridBackgroundProperty =
            DependencyProperty.Register("GridBackground", typeof(Brush), typeof(DisplayGrid), new PropertyMetadata());


        public void SetChild(UIElement child)
        {
            InitializeComponent();
            Child = child;
            

        }
        public UIElement Child
        {
            get { return (UIElement)GetValue(ChildProperty); }
            set {
                SetValue(ChildProperty, value);
              

                borderChildContainer.Child = value;
                
            }
        }

        // Using a DependencyProperty as the backing store for Child.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ChildProperty =
            DependencyProperty.Register("Child", typeof(UIElement), typeof(DisplayGrid), new FrameworkPropertyMetadata(null , FrameworkPropertyMetadataOptions.AffectsParentMeasure));


        private void StackPanel_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            this.Visibility = Visibility.Collapsed;
        }

    
    }
}





when i use this usercontrol in another project like this :



when i use this usercontrol in another project like this :

 <kl:DisplayGrid Name="dg1" Gridremoved="DarkGreen">
   <kl:DisplayGrid.Child>
      <Button Content="click" />
   </kl:DisplayGrid.Child>
</kl:DisplayGrid>





The Problem is : setting the custom dependency propert \"GridBackground\" in XAML is reflected in the designer

but setting the \"Child\" property isn’t

but setting it in the code behinde like this :



The Problem is : setting the custom dependency propert "GridBackground" in XAML is reflected in the designer
but setting the "Child" property isn't
but setting it in the code behinde like this :

Button b = new Button() { Content = "Click" , Width=250 , Height=250};
dg1.SetChild(b);



does the trick



so why is this behavior ? and what am i doing wrong ?



What I have tried:



I have Tried setting the flag in the metadata of the child property to AffectsParentMeasure

and then to AffectsMeasure

with no avail


does the trick

so why is this behavior ? and what am i doing wrong ?

What I have tried:

I have Tried setting the flag in the metadata of the child property to AffectsParentMeasure
and then to AffectsMeasure
with no avail

推荐答案

Hi,



the main problem here is that you try to do things in the set accessor for Child that it actually not called when accessed from XAML. Therefore, start by cleaning up the code-behind code by removing some lines:



Hi,

the main problem here is that you try to do things in the set accessor for Child that it actually not called when accessed from XAML. Therefore, start by cleaning up the code-behind code by removing some lines:

// !!! Suspect - never call InitializeComponent from anywhere but constructor
        //public void SetChild(UIElement child)
        //{
//InitializeComponent();
    //        Child = child;


  //      }
        public UIElement Child
        {
            get { return (UIElement)GetValue(ChildProperty); }
            set
            {
                SetValue(ChildProperty, value);

                // !!! Never do anything in a dependency accessor since it will not be called when used from XAML
                // borderChildContainer.Child = value;

            }
        }





Then, by using a ContentPresenter in your Border you can use the same approach as you seem to have used for GridBackground to bind the Child:





Then, by using a ContentPresenter in your Border you can use the same approach as you seem to have used for GridBackground to bind the Child:

<Border x:Name="borderChildContainer"

                Grid.Row="1"

                Grid.Column="1" >
            <ContentPresenter Content="{Binding Child, ElementName=uc}" />
        </Border>


这篇关于如何在设计中设置用户控件的自定义依赖项属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆