2014-02-11 3 views
3

У меня есть этот XAMLBinding/Реферирование Метод XAML WPF

<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> 

, и мой C# код:

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

Проблема заключается в том, что я получаю следующее сообщение об ошибке:

Ошибка 1
Корневой элемент ResourceDictionary требует топора: атрибут класса для поддержки событий обработчиков в файле XAML. Удалите обработчик событий для события MouseEnter, или добавьте атрибут x: Class к корневому элементу.

+0

То, что вы пытаетесь сделать ?? –

+0

Я хочу добавить много обработчиков к уникальному событию через XAML – jovanMeshkov

+0

@Jovan - Разве вы не можете использовать метод в коде для словаря ресурсов? Я не думаю, что вы можете привязать ObjectDataProvider к этому RouteEvent, и это тоже, где делегат имеет другую подпись. –

ответ

12

Ну, вы можете это сделать с кодом, прилагаемым к вашему ресурсуDictionary. Несколько простых шагов для достижения этой цели:

  • Сказать ResourceDictionary имя файла CustomResources.xaml. Добавьте другой файл в тот же каталог, кроме вашего ResourceDictionary, с именем CustomResources.xaml.cs. Создайте partial class CustomResources, наследуя от ResourceDictionary.

Объявите свой обработчик для MouseEnter и код позади готов.

using System; 
using System.Windows; 
namespace WpfApplication1 
{ 
    public partial class CustomResources : ResourceDictionary 
    { 
     public void MouseEnter(object sender, EventArgs e) 
     { 
      MessageBox.Show("Test"); 
     } 
    } 
} 
  • Теперь в XAML установить x:Class атрибут и установить обработчик MouseEnter.

XAML:

<ResourceDictionary 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      x:Class="WpfApplication.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> 
+1

Спасибо, сэр! – jovanMeshkov

+1

Добро пожаловать Jovan .. :) –

+0

Подождите, подождите ... xD Это хорошо, но как насчет того, я определил эти методы в моем классе TitledWindow, coz, который является классом, который использует этот ResourceDictionary? – jovanMeshkov

1

Проблема в том, что Template должен знать, подходит ли оно к MouseEnter. К сожалению, даже применив ваш шаблон x:Type к шаблону, компилятору xaml недостаточно.

Я сделал что-то подобное раньше, получая ResourceDictionary, чтобы распознать porepoties того, на что я морю, и похоже, что я использовал стиль, чтобы обойти его. Полный код в 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> 

Однако вы хотите, чтобы затем связать свой обработчик метода на вашем objectDataPresenter через {StaticResource ...} который я не уверен, что вы можете. Вместо этого вам может быть лучше вместо этого привязаться к DataContext, используя обычное связывание {Binding Path=...}. Думаю, вы все равно сможете предоставить DataContext через {StaticResource.. }.

+0

Но почему 'Template' должен знать, в каком классе она принадлежит, когда все, что я пытался сделать, это привязать к объекту и вытащить его метод через ключ StaticResource ... Btw ALSki, если вы хотите проверить мои: [ link] (http://stackoverflow.com/questions/21680401/wpf-custom-window-resize-issue?noredirect=1#comment32779167_21680401) Я ответил на ваш вопрос – jovanMeshkov