Binding/Referencing Method to XAML WPF

删除回忆录丶 提交于 2019-12-19 08:00:07

问题


I have this xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:l="clr-namespace:My.Windows"
                    >
    <ObjectDataProvider x:Key="TitledWindow_Test" MethodName="Test" ObjectInstance={x:Type l:TitledWindow}">
    <ControlTemplate x:Key="TitledWindowControlTemplateKey" x:Name="PART_ControlTemplate" TargetType="{x:Type l:TitledWindow}"
        <Rectangle>
            <Rectangle.Style>
                <EventSetter Event="Mouse.MouseEnter" Handler="{StaticResource TitledWindow_Test}">
            </Rectangle.Style>
        </Rectangle>
    </ControlTemplate>
</ResourceDictionary>

And my c# code:

namespace My.Windows
{
    public partial class TitledWindow : Window
    {
        public void Test()
        {
            MessageBox.Show("Test");
        }
    }
}

The problem is that i get the following error:

Error 1
'ResourceDictionary' root element requires a x:Class attribute to support event handlers in the XAML file. Either remove the event handler for the MouseEnter event, or add a x:Class attribute to the root element.


回答1:


Well you can do that by attaching code behind to your ResourceDictionary. Few simple steps to achieve that are:

  • Say ResourceDictionary file name is CustomResources.xaml. Add another file in same directory besides your ResourceDictionary with name CustomResources.xaml.cs. Create partial class CustomResources inheriting from ResourceDictionary.

Declare your handler for MouseEnter and code behind is ready.

using System;
using System.Windows;
namespace WpfApplication1
{
    public partial class CustomResources : ResourceDictionary
    {
        public void MouseEnter(object sender, EventArgs e)
        {
            MessageBox.Show("Test");
        }
    }
}
  • Now, in XAML set x:Class attribute and set handler to MouseEnter.

XAML :

<ResourceDictionary
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Class="WpfApplication1.CustomResources"
             xmlns:local="clr-namespace:WpfApplication1">
    <ControlTemplate x:Key="TitledWindowControlTemplateKey" 
                     x:Name="PART_ControlTemplate"
                     TargetType="{x:Type local:TitleWindow}">
        <Rectangle>
            <Rectangle.Style>
                <Style TargetType="Rectangle">
                    <EventSetter Event="Mouse.MouseEnter" Handler="MouseEnter"/>
                </Style>
            </Rectangle.Style>
        </Rectangle>
    </ControlTemplate>    
</ResourceDictionary>



回答2:


You need to add the x:class attribute and specify where the resource is, and where the event handler would be located. See Is it possible to set code behind a resource dictionary in WPF for event handling? for an example of this.




回答3:


The problem is that the Template needs to know if what it is being applied to has a MouseEnter. Unfortunately even by applying your x:Type to the template, the xaml compiler doesn't have enough to go on.

I have done something similar before in getting the ResourceDictionary to recognise the porepoties of what I'm templating to and it looks like I used a style to get around it. Full code in http://winchrome.codeplex.com/SourceControl/latest#WinChrome/UI/VS2012ResourceDictionary.xaml.

<ResourceDictionary ... >

<Style x:Key="CloseButtonStyle" TargetType="{x:Type Button}" >
  ...
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border x:Name="bd" ....>
                ....
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True" SourceName="bd">
                        <Setter Property="Background" TargetName="bd" Value="{DynamicResource {x:Static SystemColors.ControlLightLightBrushKey}}"/>
                        ... 
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="Background" TargetName="bd">
                          ...
                        </Setter>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

However you want to then bind your handler to a method on your objectDataPresenter via a {StaticResource ...} which I'm not sure that you can. Instead you might be better to instead bind onto the DataContext using a normal binding {Binding Path=...}, I think you might still be able to provide the DataContext via the {StaticResource.. }.



来源:https://stackoverflow.com/questions/21708553/binding-referencing-method-to-xaml-wpf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!