none
UserControl能不能自定义事件? RRS feed

  • 问题

  • 例如,我在一个UserControl控件UC1中添加了一个按钮B1,希望按下按钮后触发UC1的事件,能不能办到?

    1. 如果能,怎么办?
    2. 如果不能,能不能从外界访问UserControl里的全局变量?

    我原来的想法是:通过按下B1通知外界将UC1删除,但是似乎需要事件才能办到。

    2014年6月10日 12:07

答案

  • 你好,当然可以,我这里用C#写了一个,可以作为参考,原理很简单,点击B1的时候传出一个信号给主页面,主页面通过信号来删除当前UserControl:

    首先是你的UserControl,我在里面画了一个Button用来被点击:

    <UserControl
        x:Class="App97.MyUserControl1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App97"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="300"
        d:DesignWidth="400">
    
        <Grid>
            <Button Content="Button" HorizontalAlignment="Left" Height="112" Margin="136,87,0,0" VerticalAlignment="Top" Width="127" Click="Button_Click"/>
    
        </Grid>
    </UserControl>

    这一段是UserControl的后台代码,首先我需要注册一个Dependency Property,这样才可以把是否删除的信号传出去,这里我定义了一个Deletable的值,如果是False的话是不可删除,如果是True的话是可删除。

        public sealed partial class MyUserControl1 : UserControl
        {
            public MyUserControl1()
            {
                this.InitializeComponent();
            }
    
    
            public static readonly DependencyProperty SpeciesProperty =
                DependencyProperty.Register(
                "Deletable",
                typeof(Boolean),
                typeof(Boolean), null
                );
            public Boolean Deletable
            {
                get { return (Boolean)GetValue(SpeciesProperty); }
                set { SetValue(SpeciesProperty, (Boolean)value); }
            }
    
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                Deletable = true;
            }
        }

    XAML放置进去:

    <Page
        x:Class="App97.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App97"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
            <StackPanel x:Name="stp">
                <local:MyUserControl1 x:Name="mycontrol"></local:MyUserControl1>
            </StackPanel>
        </Grid>
    </Page>
    

    下面这一段是后台代码,主要功能是通过监听UserControl的Deletable属性来看是否可以把UserControl删除:

        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
    
                DispatcherTimer timer = new DispatcherTimer();
                timer.Tick += timer_tick;
                timer.Interval = new TimeSpan(0, 0, 0, 0, 1);
                timer.Start();
    
            }
    
            private void timer_tick(object sender, object e)
            {
               if(mycontrol.Deletable)
               {
                   stp.Children.Remove(mycontrol);
               }
            }
    
        }

    --James

    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    2014年6月11日 6:28
    版主
  • 你好,lxylxy,

    你的方法是不行的,可以参考一下文档:Custom dependency properties。

    我这里写个一个简单的例子,你看一下,是关于如何注册Dependency properities的,我这里注册了一个叫Deletable的String类,你可以改成Boolean类型如果你愿意的话:

    CPP:
    
    DependencyProperty^ MyUserControl::_LabelProperty = DependencyProperty::Register("Deletable", Platform::String::typeid, MyUserControl::typeid, nullptr);
    
    
    void App99::MyUserControl::Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
    {
    	//this->LabelProperty = "true";
    	this->Deletable = "yes";
    }
    H:
    
    using namespace Windows::UI::Xaml::Controls;
    using namespace Windows::UI::Xaml::Interop;
    using namespace Windows::UI::Xaml;
    using namespace Windows::UI::Xaml::Media;
    using namespace Platform;
    
    	public ref class MyUserControl sealed
    	{
    	public:
    		MyUserControl();
    		
    
    		static property DependencyProperty^ LabelProperty
    		{
    			DependencyProperty^ get() { return _LabelProperty; }
    		}
    
    		property String^ Deletable
    		{
    			String^ get() { return (String^)GetValue(LabelProperty); }
    			void set(String^ value) { SetValue(LabelProperty, value); }
    		}
    	private:
    		void Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
    		static DependencyProperty^ _LabelProperty;
    
    	};

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    2014年6月16日 9:38
    版主
  • 好的,我上传到SkyDrive上:http://1drv.ms/1lMrfdc

    我使用的是VS2013,如果你用的VS2012做项目的话,可以直接把代码粘贴复制到你项目对应的文件中即可。

    编译之后应该可以看到 Deletable属性出现在控件属性列表中了。

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    2014年6月17日 8:22
    版主
  • 似乎把.xaml.h文件中的命名空间声明放到#pragma once前面就好了,我再试一试
    2014年6月17日 9:10

全部回复

  • 你好,当然可以,我这里用C#写了一个,可以作为参考,原理很简单,点击B1的时候传出一个信号给主页面,主页面通过信号来删除当前UserControl:

    首先是你的UserControl,我在里面画了一个Button用来被点击:

    <UserControl
        x:Class="App97.MyUserControl1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App97"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="300"
        d:DesignWidth="400">
    
        <Grid>
            <Button Content="Button" HorizontalAlignment="Left" Height="112" Margin="136,87,0,0" VerticalAlignment="Top" Width="127" Click="Button_Click"/>
    
        </Grid>
    </UserControl>

    这一段是UserControl的后台代码,首先我需要注册一个Dependency Property,这样才可以把是否删除的信号传出去,这里我定义了一个Deletable的值,如果是False的话是不可删除,如果是True的话是可删除。

        public sealed partial class MyUserControl1 : UserControl
        {
            public MyUserControl1()
            {
                this.InitializeComponent();
            }
    
    
            public static readonly DependencyProperty SpeciesProperty =
                DependencyProperty.Register(
                "Deletable",
                typeof(Boolean),
                typeof(Boolean), null
                );
            public Boolean Deletable
            {
                get { return (Boolean)GetValue(SpeciesProperty); }
                set { SetValue(SpeciesProperty, (Boolean)value); }
            }
    
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                Deletable = true;
            }
        }

    XAML放置进去:

    <Page
        x:Class="App97.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App97"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
            <StackPanel x:Name="stp">
                <local:MyUserControl1 x:Name="mycontrol"></local:MyUserControl1>
            </StackPanel>
        </Grid>
    </Page>
    

    下面这一段是后台代码,主要功能是通过监听UserControl的Deletable属性来看是否可以把UserControl删除:

        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
    
                DispatcherTimer timer = new DispatcherTimer();
                timer.Tick += timer_tick;
                timer.Interval = new TimeSpan(0, 0, 0, 0, 1);
                timer.Start();
    
            }
    
            private void timer_tick(object sender, object e)
            {
               if(mycontrol.Deletable)
               {
                   stp.Children.Remove(mycontrol);
               }
            }
    
        }

    --James

    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    2014年6月11日 6:28
    版主
  • 我没能访问Deleteable,无论是在usercontrol内部还是外部。

    你能不能把定义Deleteable的代码写成C++的?

    //在MyUserControl.xaml.h中
    namespace 工程名
    {
    	[Windows::Foundation::Metadata::WebHostHidden]
    	public ref class Page7UserControl1 sealed
    	{
    	public:
    		Page7UserControl1();
    		Boolean Delerable = false;//这个属性没有被访问到
    	private:
    		//略
    	};
    }
    似乎是需要进行DependencyProperty::Register,但是我不知道怎么写C++代码(错误百出)

    2014年6月11日 10:46
  • 你好,lxylxy,

    你的方法是不行的,可以参考一下文档:Custom dependency properties。

    我这里写个一个简单的例子,你看一下,是关于如何注册Dependency properities的,我这里注册了一个叫Deletable的String类,你可以改成Boolean类型如果你愿意的话:

    CPP:
    
    DependencyProperty^ MyUserControl::_LabelProperty = DependencyProperty::Register("Deletable", Platform::String::typeid, MyUserControl::typeid, nullptr);
    
    
    void App99::MyUserControl::Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
    {
    	//this->LabelProperty = "true";
    	this->Deletable = "yes";
    }
    H:
    
    using namespace Windows::UI::Xaml::Controls;
    using namespace Windows::UI::Xaml::Interop;
    using namespace Windows::UI::Xaml;
    using namespace Windows::UI::Xaml::Media;
    using namespace Platform;
    
    	public ref class MyUserControl sealed
    	{
    	public:
    		MyUserControl();
    		
    
    		static property DependencyProperty^ LabelProperty
    		{
    			DependencyProperty^ get() { return _LabelProperty; }
    		}
    
    		property String^ Deletable
    		{
    			String^ get() { return (String^)GetValue(LabelProperty); }
    			void set(String^ value) { SetValue(LabelProperty, value); }
    		}
    	private:
    		void Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
    		static DependencyProperty^ _LabelProperty;
    
    	};

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    2014年6月16日 9:38
    版主
  • 出现错误:(应用名是"实验",使用UserControl的是"Page7",UserControl的名称是"Page7Usercontrol1")

    错误	1	error LNK2001: 无法解析的外部符号 "private: static class Windows::UI::Xaml::DependencyProperty ^ 实验::Page7UserControl1::_LabelProperty" (?_LabelProperty@Page7UserControl1@实验@@0P$AAVDependencyProperty@Xaml@UI@Windows@@$AA)	实验\Page7.xaml.obj
    错误	2	error LNK2001: 无法解析的外部符号 "private: static class Windows::UI::Xaml::DependencyProperty ^ 实验::Page7UserControl1::_LabelProperty" (?_LabelProperty@Page7UserControl1@实验@@0P$AAVDependencyProperty@Xaml@UI@Windows@@$AA)	实验\Page7UserControl1.xaml.obj
    错误	3	error LNK2001: 无法解析的外部符号 "private: static class Windows::UI::Xaml::DependencyProperty ^ 实验::Page7UserControl1::_LabelProperty" (?_LabelProperty@Page7UserControl1@实验@@0P$AAVDependencyProperty@Xaml@UI@Windows@@$AA)	实验\XamlTypeInfo.g.obj
    错误	4	error LNK1120: 1 个无法解析的外部命令	实验.exe	1

    那个

    static property DependencyProperty^ LabelProperty{ DependencyProperty^ get(){ return _LabelProperty; }; }

    有问题,似乎是在引用_LabelProperty时的错误。



    2014年6月16日 10:51
  • 你好,我认为你应该自己去研究一下代码,我这里运行是完全正确的才会把代码贴给你,你或许应该检查下Class的名字或者你的代码中是否多了空格亦或者其他问题。:)

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    2014年6月16日 11:25
    版主
  • 我没有遇到过这种问题,也不知道怎么解决。就是在

    static property DependencyProperty^ LabelProperty

    {

    DependencyProperty^ get() { return _LabelProperty; }

    }


    中如果有_LabelProperty就会报错,如果没有就不会。你能不能把项目发给我?(用onedrive或者别的网盘?)

    2014年6月16日 11:53
  • 好的,我上传到SkyDrive上:http://1drv.ms/1lMrfdc

    我使用的是VS2013,如果你用的VS2012做项目的话,可以直接把代码粘贴复制到你项目对应的文件中即可。

    编译之后应该可以看到 Deletable属性出现在控件属性列表中了。

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    2014年6月17日 8:22
    版主
  • 似乎把.xaml.h文件中的命名空间声明放到#pragma once前面就好了,我再试一试
    2014年6月17日 9:10
  • 能不能用类似的方法定义事件?如果能,怎样触发?
    2014年6月17日 10:50