Call events or methods located in a Class from XAML

前端 未结 2 1923
名媛妹妹
名媛妹妹 2021-01-27 03:54

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

相关标签:
2条回答
  • 2021-01-27 04:19

    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)
        {
        }
    }
    
    0 讨论(0)
  • 2021-01-27 04:25

    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.
    }
    
    0 讨论(0)
提交回复
热议问题