【问题标题】:Button listener on a user control用户控件上的按钮侦听器
【发布时间】:2012-12-22 14:40:44
【问题描述】:

问题来了:

我有一个带有监听器的“主页按钮”

    private void Item_Tap(object sender, TappedRoutedEventArgs e)
    {
        if (this.Frame != null)
        {
            this.Frame.Navigate(typeof(Home));
        }
    }

如果我构建了一个用户控件,使用里面的“主页按钮”,我怎样才能完成相同的导航?

** 我已经接近解决方案**。 这是用户控件:

public sealed partial class TopBarControl : UserControl
    {
        public Frame Frame { get; set; }
        public object Parameter { get; set; }
        public TopBarControl(Frame frame)
        {
            this.InitializeComponent();
            this.Frame = frame;
            var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
            var dateAndTime = DateTime.Now;
            Date.Text = dateAndTime.Date.ToString("MM/dd/yyyy");
            User.Text = localSettings.Values["userName"].ToString();
            //SectionTitle.Text = Parameter.ToString();
        }

        private void GoHome_Tap(object sender, TappedRoutedEventArgs e)
        {
            if (this.Frame != null)
            {
                this.Frame.Navigate(typeof(Main_Menu));
            }
        }
    }

在我拥有的 xaml 用户控件上:

<Button Grid.Column="0" HorizontalAlignment="Right" BorderThickness="0">
    <Image Source="/Assets/home_icon.png" Tapped="GoHome_Tap"/>
</Button>

与用户控件关联的页面

public WantedVehicles()
        {
            this.InitializeComponent();
        }

        private TopBarControl topBarControl;
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            Tit.Text = e.Parameter.ToString();
            topBarControl.Frame = this.Frame;
            topBarControl.Parameter = e.Parameter;
        }

 protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
        {
        }
protected override void SaveState(Dictionary<String, Object> pageState)
        {
        }

但是按钮还不能用。

【问题讨论】:

    标签: c# xaml user-controls microsoft-metro listener


    【解决方案1】:

    我了解您的问题。这是创建主页按钮的简单方法,您可以将其添加到应用程序的任何位置,然后它会导航到主页。无需级联事件或类似的东西。只需创建一个自定义控件。 这与用户控件不同。这只是对按钮控件进行子分类。更干净的方法。

    三个简单的步骤。

    注意:我的自定义控件将被称为 HomeButton,而我的主页类将被称为 HomePage。除此之外,这对你来说应该是开箱即用的。

    首先,定义按钮的外观:

    <!-- custom home button -->
    <Style TargetType="local:HomeButton" BasedOn="{StaticResource BackButtonStyle}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid Height="48" Width="48">
                        <Ellipse Stroke="White" StrokeThickness="2" />
                        <TextBlock Text="&#xE10F;" FontSize="20" 
                                   VerticalAlignment="Center" HorizontalAlignment="Center" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    其次,像这样定义您的自定义控件:

    public sealed class HomeButton : Button
    {
        public HomeButton()
        {
            this.DefaultStyleKey = this.GetType();
            this.Click += HomeButton_Click;
        }
    
        void HomeButton_Click(object sender, RoutedEventArgs e)
        {
            var _Frame = Window.Current.Content as Frame;
            var _Type = typeof(HomePage);
            _Frame.Navigate(_Type);
        }
    }
    

    第三,也是最后,将主页按钮添加到您的应用中!

    <local:HomeButton HorizontalAlignment="Left" VerticalAlignment="Top" Margin="40" />
    

    它的外观如下:

    它甚至可以工作! :) 如果您想为按钮设置更多样式,很容易在 /Common/StandardStyles.xaml 文件中窃取 BackButtonStyle 的样式。然后你可以拥有相同的视图状态和所有。无论如何,这会让你到达你想要的地方。

    所以,这是解决您在问题中描述的问题的主页按钮。它甚至以比您假设的解决方案更少问题的方式解决它 - 因为跨上下文手动冒泡事件可能会导致噩梦。

    我希望这会有所帮助。

    【讨论】:

    • 顺便说一句,尝试在按钮中使用矢量图像而不是 PNG 或 JPG 文件很重要。这不是因为这些文件不起作用。这是因为向量在被禁用时正确地“变暗”。图像保持明亮的“白色”,只会导致更多问题。这是一个普遍的原则。因为您是从头开始设计自己的按钮,所以也可以合并图像的启用和禁用版本,但为什么呢? blog.jerrynixon.com/2012/03/… & timheuer.com/blog/archive/2012/09/03/…
    • 如果你有兴趣,我在博客上写了这个答案blog.jerrynixon.com/2013/01/…
    【解决方案2】:

    向您的用户控件添加一个按钮,并将Item_Tap 事件处理程序附加到它。

    <UserControl>
      ....
      <Button  Tapped="GoHome_Tap">Go Home</Button>
     .....
    </UserControl>
    

    Frame 添加到 MyUserControl.cs。请参阅您的 other question 以了解如何从封闭的 Page 设置 Frame 属性。

     public TopBarControl:UserControl
     {
        public Frame Frame {get;set;} // To be set in either OnNavigatedTo, or in Constructor. 
    
     }
    

    将事件处理程序添加到 MyUserControl.cs

    private void GoHome_Tap(object sender, TappedRoutedEventArgs e)
    {
        if (this.Frame != null)
        {
            this.Frame.Navigate(typeof(Home));
        }
    }
    

    【讨论】:

    • "向您的用户控件添加一个按钮,并将 Item_Tap 事件处理程序附加到它。"你是说 GoHome_Tap 事件?顺便说一下,我根据实际情况更新了问题。
    • 你没有设置Frame。我已经更新了答案。您可以在构造函数中接受 Frame。你能显示你正在创建 TopBarControl 用户控件的页面/窗口代码吗?
    • 这给了我一个错误“MyUserControl.cs 不包含接受 0 个参数的构造函数”。我用您问的代码更新了问题:用户控件没有任何内容,我在 xaml 中使用它。
    • 在导航到的on中,在WantedVehicles类中添加myUserControl.Frame = this.Frame这一行
    • 也许我们正处于关键时刻。我收到此错误“无法构建类型 MyUserControl XAML。要在 XAML 中构建,类型不能是抽象、接口、嵌套或泛型结构,并且必须具有公共默认构造函数”。在问题中,我再次更新了实际代码。
    【解决方案3】:

    您必须向您的 UserControl 添加一个在按钮的事件处理程序中触发的事件。您在上面发布的事件仍将在您的用户控件之外定义,除非您将任何“this”传递给 UserControl 的构造函数。

    【讨论】:

    • 假设我在 UserControl 中创建了“GoHome_Tap”。如何在其中调用函数“Item_Tap”?
    猜你喜欢
    • 2015-07-31
    • 1970-01-01
    • 2013-11-23
    • 1970-01-01
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-06
    相关资源
    最近更新 更多