在ResourceDictionary中为DataTemplate分配事件或命令

时间:2010-03-26 21:20:48

标签: c# wpf xaml

我有以下课程:

public class Day
{
    public int Date { get; set; }
    public String DayName { get; set; }

    public Day()
    {

    }

    public Day(int date, string dayName)
    {
        Date = date;
        DayName = dayName;

        CommandManager.RegisterClassCommandBinding(typeof(Day), new CommandBinding(DayClick, new ExecutedRoutedEventHandler(OnExecutedDayClick), 
            new CanExecuteRoutedEventHandler(OnCanExecuteDayClick)));
    }

    public static readonly RoutedCommand DayClick = new RoutedCommand("DayClick", typeof(Day));

    private static void OnCanExecuteDayClick(object sender, CanExecuteRoutedEventArgs e)
    {
        ((Day)sender).OnCanExecuteDayClick(e);
    }

    private static void OnExecutedDayClick(object sender, ExecutedRoutedEventArgs e)
    {
        ((Day)sender).OnExecutedDayClick(e);
    }

    protected virtual void OnCanExecuteDayClick(CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = true;
        e.Handled = false;
    }

    protected virtual void OnExecutedDayClick(ExecutedRoutedEventArgs e)
    {
        string content = String.Format("Day {0}, which is {1}, was clicked.", Date.ToString(), DayName);
        MessageBox.Show(content);
        e.Handled = true;
    }
}

我正在使用以下DataTemplate(在ResourceDictionary中)来呈现它:

<DataTemplate DataType="{x:Type local:Day}">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Rectangle Grid.ColumnSpan="2" x:Name="rectHasEntry" Fill="WhiteSmoke"/>
        <TextBlock Grid.Column="0" x:Name="textBlockDayName" Text="{Binding DayName}" 
                               FontFamily="Junction" FontSize="11" Background="Transparent" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,2,0,0"/>
        <TextBlock Grid.Column="1" x:Name="textBlockDate" Text="{Binding Date}" 
                               FontFamily="Junction" FontSize="11" Background="Transparent" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,2,0,0"/>
        <Rectangle Grid.ColumnSpan="2" x:Name="rectMouseOver" Fill="#A2C0DA" Opacity="0"
                               Style="{StaticResource DayRectangleMouseOverStyle}">
        </Rectangle>
    </Grid>
</DataTemplate>

到目前为止没问题,我可以在屏幕上看到它。

我希望能够做的是分配一个命令,或者使用一个事件,这样当用户点击该日时,它将通知Day对象的父项已被点击。

我尝试了以下内容:

<Rectangle.CommandBindings>
    <CommandBinding Command="{x:Static local:Day.NextDay}"
                             Executed="{x:Static local:Day.OnExecutedDayClick}"
                             CanExecute="{x:Static local:Day.OnCanExecuteDayClick}"/>
</Rectangle.CommandBindings>

尝试绑定Day类中的命令,但它不起作用。我收到一条错误说明:

  

'ResourceDictionary'根元素需要x:Class属性来支持XAML文件中的事件处理程序。删除Executed事件的事件处理程序,或将x:Class属性添加到根元素。

我认为这意味着没有ResourceDictionary的代码隐藏文件,或者是那种效果。

无论如何,我不确定我是否应该在这里使用命令,或者以某种方式将事件绑定到有问题的Rectangle,或者这是否可能。我已经看到了各种确定看起来有可能的地方,我只是无法将我所看到的东西翻译成实际可行的东西,因此这篇文章。

提前致谢。

1 个答案:

答案 0 :(得分:4)

您不能在此声明CommandBinding,在这种情况下,您可以在DataTemplate中分配命令,并在主窗口或页面中声明CommandBinding。

编辑:

通过这种方式,您可以将命令与自定义控件一起使用。 在控件本身内创建一个自定义控件和声明命令和命令绑定,如本示例所示。

MyCustomControl.cs

    static MyCustomControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl)));
        InitializeCommands();
    }

    private static RoutedCommand _myCommand;

    public static RoutedCommand MyCommand
    {
        get
        {
            return _myCommand;
        }
    }

    private static void InitializeCommands()
    {
        _myCommand = new RoutedCommand("MyCommand", typeof(MyCustomControl));
        CommandManager.RegisterClassCommandBinding(typeof(MyCustomControl),
                                new CommandBinding(_myCommand , OnMyCommandExecute));
    }

    private static void OnMyCommandExecute(object sender, ExecutedRoutedEventArgs e)
    {
        MyCustomControl control = sender as MyCustomControl;
        if (control != null)
        {
            //logic for this command
        }
    }

并在您的generic.xaml中编写此样式并分配如下命令:

generic.xaml

<Style TargetType="{x:Type local:MyCustomControl}">
    <Setter Property="HorizontalAlignment" Value="Center"/>
    <Setter Property="VerticalAlignment" Value="Center"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MyCustomControl}">
                <Grid>
                    <RepeatButton Command="{x:Static local:MyCustomControl.MyCommand}"  >Click</RepeatButton>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>