Вызывать события или методы, расположенные в классе из XAML - PullRequest
1 голос
/ 23 апреля 2011

Привет, я пытаюсь, если возможно, чтобы событие вроде TextChanged (из TextBox) находилось в другом месте, не зависящем от Window CodeBehind (как у класса).

То, что я пытаюсь сделать, это иметь вResourceDictionary - ссылка на событие TextBox.(Поскольку у ResourcesDictionaries нет CodeBehind.)

Примечание: это действительно должно быть так, потому что я настраиваю другой элемент управления, чтобы иметь некоторые TextBoxes динамически, и все TextBoxes будут запускать одно и то же событие, когдаTextChanged происходит.

Ответы [ 2 ]

2 голосов
/ 23 апреля 2011

Я бы предложил триггеры. Подробнее о них можно прочитать здесь: http://www.silverlightshow.net/items/Behaviors-and-Triggers-in-Silverlight-3.aspx

По сути, в xaml вы можете привязать событие элемента управления к триггеру и заставить его выполнить метод или команду еще где.

Edit: я должен отметить, что хотя он и говорит «Silverlight», все это относится и к WPF. Edit2: инструментарий MVVM предоставляет EventToCommandTrigger, который позволит вам сделать что-то вроде этого:

http://blog.galasoft.ch/archive/2009/11/05/mvvm-light-toolkit-v3-alpha-2-eventtocommand-behavior.aspx

Престижность ответа Х.Б. за напоминание о командном способе сделать это

Edit3: лучший пример, это во многом зависит от того, как мир MVVM сделает это. Поскольку привязка EventToCommand будет привязана к какому-либо контексту элемента управления, вы можете вставить это в свой ResourceDictionary и в любое место, где вы его разместите, он попытается найти это свойство TextChangeCommand.

 <Window x:Class="TestBed.TestWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras">
    <Grid>
        <TextBox x:Name = "MyTextBox">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="TextChanged">
                    <cmd:EventToCommand Command="{Binding TextChanged, Mode=OneWay}"
                                        CommandParameter="{Binding Text, 
                                              ElementName=MyTextBox, Mode=OneWay}"
                        MustToggleIsEnabledValue="True" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </TextBox>
    </Grid>
</Window>

и код:

public partial class TestWindow : Window
{
    public TestWindow()
    {
        this.TextChangedCommand = new RelayCommand<string>(
            (str) => TextChanged(str));

        InitializeComponent();
    }

    public RelayCommand<string> TextChangedCommand
    {
        get;
        private set;
    }

    public void TextChanged(string str)
    {
    }
}
0 голосов
/ 23 апреля 2011

Редактировать: Не обращайте на это внимания, если только вы не хотите создать подкласс TextBox для выполнения команды над TextChanged. (Я думаю, что триггерный метод должен быть предпочтительным.)

Но возможно сделать ссылку на Ресурсные словари к событию расположенный в CodeBehind of Окно, где этот элемент управления? Представьте себе следующее, а не мы устанавливают событие для элемента управления в XAML, мы делаем это в словаре в стиле. Это возможно?

Я бы предложил Команды для этого; определить где-нибудь RoutedCommand:

public static class Commands
{
    public static RoutedCommand DoStuff = new RoutedCommand();
}

Установите его на кнопку в словаре:

<Button x:Key="TheButton" Content="Click"
        Command="{x:Static local:Commands.DoStuff}" />

И создайте привязку команды:

<Grid>
    <Grid.CommandBindings>
        <CommandBinding Command="{x:Static local:Commands.DoStuff}"
                        Executed="DoStuff_Executed"
                        CanExecute="DoStuff_CanExecute"/>
    </Grid.CommandBindings>
    <StaticResource ResourceKey="TheButton"/>
</Grid>
private void DoStuff_Executed(object sender, ExecutedRoutedEventArgs e)
{
    // What happens if the command is executed, in this case the Button-click can
    // cause this to happen, you can also create KeyBindings which can execute
    // commands for example.
    MessageBox.Show("!");
}
private void DoStuff_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = true; //No condition: Command can always be executed

    // e.CanExecute = false causes the button to be disabled.
}
...