WPF中弹出窗口内的按钮点击事件有什么想法吗?

时间:2013-11-07 06:15:44

标签: wpf events c#-4.0 wpf-controls

我正在尝试实现Datepicker控件的Outlook样式的功能。

我有一个文本框,它正在应用一个与Outlook完全相同的样式,但我的问题是弹出一个日历和两个按钮为今天和无。只要点击今天按钮,文本框值应设置为今天的日期如果我单击“无”,则文本框值必须设置为“无”。

我使用的风格是

         <Style x:Key="tbCalendarStyle" TargetType="{x:Type TextBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Grid>
                    <Border BorderThickness="1" BorderBrush="DarkGray">
                        <ScrollViewer x:Name="PART_ContentHost" />
                    </Border>
                    <ToggleButton Template="{StaticResource IconButton}"
                          MaxHeight="21" 
                          Margin="-1,0,0,0" 
                          Name="PopUpImageButton" 
                          Focusable="False"
                          IsChecked="False">
                        <ToggleButton.Content>
                            <Path x:Name="btnArrow4" Margin="4" VerticalAlignment="Center" Width="10" Fill="Black" Stretch="Uniform" HorizontalAlignment="Right" Data="F1 M 301.14,-189.041L 311.57,-189.041L 306.355,-182.942L 301.14,-189.041 Z "/>
                        </ToggleButton.Content>                        


                    </ToggleButton>
                    <Popup IsOpen="{Binding Path=IsChecked, ElementName=PopUpImageButton, Mode=TwoWay}" x:Name="CustomPopup" Margin="0,-1,0,0" PopupAnimation="Fade" StaysOpen="False">

                        <StackPanel Orientation="Vertical" removed="BlueViolet">
                            <Grid >
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="164"/>
                                    <RowDefinition Height="10"/>
                                </Grid.RowDefinitions>
                                <Calendar Grid.Row="0" Margin="0,-1,0,0" x:Name="CalDisplay"
                                  SelectedDate="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Text, Mode=TwoWay, Converter={StaticResource calendarConverter}}" 
                                  Focusable="False" 
                                  DisplayDate="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Text, Mode=OneWay, Converter={StaticResource calendarConverter}}"    
                                  >
                                    <Control.Triggers>
                                        <EventTrigger RoutedEvent="Calendar.SelectedDatesChanged">
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <BooleanAnimationUsingKeyFrames Storyboard.TargetName="PopUpImageButton" Storyboard.TargetProperty="IsChecked">
                                                        <DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="False"></DiscreteBooleanKeyFrame>
                                                    </BooleanAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </EventTrigger>
                                    </Control.Triggers>
                                </Calendar>
                            </Grid>
                            <StackPanel Orientation="Horizontal" FlowDirection="LeftToRight">
                                <Button Content="Today" Grid.Row="1" Width="50" VerticalAlignment="Center" Margin="20 0 0 10" Name="btnToday">
                                    <Button.Triggers>
                                        <EventTrigger RoutedEvent="Button.Click">
                                            // what should i do to achieve the above logic
                                        </EventTrigger>
                                    </Button.Triggers>
                                </Button>

                                <Button Content="None" Grid.Row="1" Margin="30 0 0 10" Width="50" VerticalAlignment="Center" Name="btnNone">
                                    <Button.Triggers>
                                        <EventTrigger RoutedEvent="Button.Click">

                                        </EventTrigger>
                                    </Button.Triggers>
                                </Button>
                            </StackPanel>
                        </StackPanel>
                    </Popup>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="true">
                        <Setter Property="Visibility" TargetName="PopUpImageButton" Value="Visible" />
                    </Trigger>
                    <Trigger Property="IsFocused" Value="true">
                        <Setter Property="Visibility" TargetName="PopUpImageButton" Value="Visible" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    </Style>

任何有助于实现这一目标的帮助或想法都将受到高度赞赏。

2 个答案:

答案 0 :(得分:1)

如果你有一个自定义控件,那么我建议你覆盖OnApplyTemplate方法,并使用GetTemplatedChild找到Button,订阅它的点击就可以了,除非你必须找到TextBox并在处理程序中设置它的Text。 / p>

如果由于某种原因你不能这样做,这是一个小技巧,如何让它仍然有用

看看这个:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    x:Class="WPFControls.Generic"
                    xmlns:local="clr-namespace:WPFControls">

<Style TargetType="{x:Type local:MyChildControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MyChildControl}">
                <Border Background="{TemplateBinding Background}"
                        SnapsToDevicePixels="True">
                    <StackPanel>
                        <TextBox x:Name="tbx1"/>
                        <Button Content="{TemplateBinding Content}" Click="OnClick"/>
                    </StackPanel>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
....

这是Generic.xaml词典背后的代码。

public partial class Generic
{
    public void OnClick(object sender, RoutedEventArgs e)
    {
        MyChildControl control = FindAncestor<MyChildControl>((DependencyObject)sender);
        TextBox tbx = control.Template.FindName("tbx1", control) as TextBox;
        tbx.Text = "It works!";
    }

    public static T FindAncestor<T>(DependencyObject current) where T : DependencyObject
    {
        current = VisualTreeHelper.GetParent(current);

        while (current != null)
        {
            if (current is T)
            {
                return (T)current;
            }

            current = VisualTreeHelper.GetParent(current);
        };

        return null;
    }
}

这是我的MainWindow.xaml:

<Window ....>
    <Grid>
        <local:MyChildControl Content="Click me!"/>
    </Grid>
</Window>

答案 1 :(得分:0)

将事件处理程序附加到ControlTemplate中定义的元素的一般方法是覆盖FrameworkElement.OnApplyTemplate方法:

public override void OnApplyTemplate()
{
    Button button = (Button)Template.FindName("btnToday", this);
    button.Click += SomeClickHandler;
}

更新&gt;&gt;&gt;

我在上面使用this(作为第二个输入参数),它代表templatedParent输入参数。正确的值取决于Template应用于哪个对象...在这种情况下,我认为它应该是this对象。

更新2&gt;&gt;&gt;

抱歉,我认为你可以写一个Click事件处理程序。这是一个:

private void SomeClickHandler(object sender, RoutedEventArgs e)
{
    // Set your DateTime here
}