从 XAML 调用位于类中的事件或方法

发布于 2024-11-03 06:02:07 字数 254 浏览 11 评论 0原文

您好,我正在尝试是否有可能将像 TextChanged (文本框的)这样的事件位于独立于窗口代码隐藏(如类)的另一个位置。

我想做的是在 ResourceDictionary 中引用 TextBox 的事件。 (因为 ResourcesDictionaries 没有 CodeBehind。)

注意:确实必须采用这种方式,因为我正在自定义另一个控件以动态地拥有一些 TextBox,并且当 TextChanged 发生时所有 TextBox 都会触发相同的事件。

Hi i am trying if it's possible having an Event like TextChanged (of a TextBox) located in another place independent of the Window CodeBehind (like a Class).

What i am trying to do is having in the ResourceDictionary a reference to an event of the TextBox. (Because the ResourcesDictionaries doesn't have a CodeBehind.)

Note: It really have to be by this way, because i am customizing another control to have some TextBoxes dynamically and all the TextBoxes will fire the same event when TextChanged occurs.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你好,陌生人 2024-11-10 06:02:07

我会建议触发器。您可以在这里阅读有关它们的更多信息: http://www .silverlightshow.net/items/Behaviors-and-Triggers-in-Silverlight-3.aspx

本质上,您可以在 xaml 中将控件的事件挂钩到触发器,并让它在其他位置执行方法或命令。

编辑:我应该注意到,虽然它确实说“Silverlight”,但它也适用于 WPF。
Edit2:MVVM工具包提供了一个EventToCommandTrigger,可以让你做这样的事情:

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

感谢 HB 的回答,提醒我执行此操作的命令方式

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)
    {
    }
}

I would suggest triggers. You can read more about them here: http://www.silverlightshow.net/items/Behaviors-and-Triggers-in-Silverlight-3.aspx

Essentially you can, in xaml, hook a control's event to a trigger and have it execute a method or command else where.

Edit: I should note that while it does say 'Silverlight' it all applies to WPF as well.
Edit2: The MVVM toolkit provides an EventToCommandTrigger that would let you do something like this:

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

Kudos to H.B.'s answer for reminding me about the command way of doing this

Edit3: Better example, this borrows heavily from how the MVVM world would do this. Since the EventToCommand binding would attached to whatever the control's context is, you could stick this in your ResourceDictionary and anywhere you place it, it would attempt to find that TextChangeCommand property.

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

and the codebehind:

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)
    {
    }
}
遗忘曾经 2024-11-10 06:02:07

编辑: 除非您想子类化 TextBox 以在 TextChanged 上执行命令,否则请忽略此设置。 (我认为触发方法是首选。)

但是可以参考
事件的资源字典
位于CodeBehind中
该控件所属的窗口?
想象一下下面的情况,而不是我们
正在将事件设置为控件
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.
}

Edit: Disregard this unless you want to subclass TextBox to execute a command on TextChanged. (I think the trigger-method is to be preferred.)

But it's possible making reference in
ResourceDictionaries to an Event
located in the CodeBehind of the
Window where that control belongs?
Imagine the following, instead of we
are setting an Event to a Control in
the XAML, we do that in the dictionary
in a style. That is possible?

I would suggest Commands for this; define a RoutedCommand somewhere:

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

Set it to the button in the dictionary:

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

And create a command binding:

<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.
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文