从WPF第一控制执行上第二控制的方法(Execute a method on second cont

2019-10-30 13:23发布

ViewControl有一个名为方法ZoomIn() 我怎么能执行这个这个方法ViewControl通过点击Button控制,无需去后台代码。

<controls:ViewControl/>
<Button Content="Zoom In"/>

ViewControl.xaml.cs:

    public void ZoomIn()
    {
        double actualWidth = m_child.ActualWidth;
        double actualHeight = m_child.ActualHeight;

        double x = (0.5 * actualWidth - Dx) / Scale;
        double y = (0.5 * actualHeight - Dy) / Scale;

        float startScale = Scale;

        Scale = Math.Min(Scale * ZoomFactor, ZoomMax);

        Dx = (float)x * (startScale - Scale) + Dx;
        Dy = (float)y * (startScale - Scale) + Dy;
    }

虽然我有一个视图模型,并尝试使用MVVM为我设计的。 我不知道它是如何可能在这种情况下作为ZoomIn()做一些事情,是观有关。

我能想到的一个类似的例子是,当我有一个按钮和一个文本框,我想点击按钮时要调用的全选()方法在文本框。

Answer 1:

实际上,有几种不同的方式来做到这一点,一个解决方案是结合使用行为和包装类的事件。 首先定义您的视图模型将触发该事件的包装:

public class EventTriggerWrapper
{
    public event EventHandler OnTriggered;

    public void Trigger()
    {
        this.OnTriggered?.Invoke(this, EventArgs.Empty);
    }
}

出于演示的目的,这里有一个按钮和一个web浏览器的一些XAML,我将使用包装的实例在视图模型来触发网络broswer的Navigate()无论何时按下按钮功能:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
    </Grid.RowDefinitions>

    <Button Content="Click Me" Command="{Binding NavigateCommand}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10" />        

    <WebBrowser Grid.Row="1">
        <i:Interaction.Behaviors>
            <behaviors:MyCustomBehavior EventTrigger="{Binding EventTrigger}" />
        </i:Interaction.Behaviors>
    </WebBrowser>

</Grid>

你可以看到,我添加了一个自定义行为的Web浏览器控件,并将其绑定到称为视图模型属性EventTrigger 。 你需要与按钮到您的视图模型的一个命令处理程序以及补充一点:

public class MainViewModel
{
    public EventTriggerWrapper EventTrigger { get; } = new EventTriggerWrapper();

    private ICommand _NavigateCommand;
    public ICommand NavigateCommand => this._NavigateCommand ?? (this._NavigateCommand = new RelayCommand(OnNavigate));

    private void OnNavigate()
    {
        this.EventTrigger.Trigger();
    }
}

因此,所有剩下的以创建与订阅事件,然后调用任何你想要在你的目标控制功能属性的行为:

public class MyCustomBehavior : Behavior<WebBrowser>
{
    public EventTriggerWrapper EventTrigger
    {
        get { return (EventTriggerWrapper)GetValue(EventTriggerProperty); }
        set { SetValue(EventTriggerProperty, value); }
    }

    // Using a DependencyProperty as the backing store for EventTrigger.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty EventTriggerProperty =
        DependencyProperty.Register("EventTrigger", typeof(EventTriggerWrapper), typeof(MyCustomBehavior), new PropertyMetadata(null, OnEventTriggerChanged));

    private static void OnEventTriggerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var behaviour = d as MyCustomBehavior;
        var oldValue = e.OldValue as EventTriggerWrapper;
        if (oldValue != null)
            oldValue.OnTriggered -= behaviour.OnEventTriggered;
        var newValue = e.NewValue as EventTriggerWrapper;
        if (newValue != null)
            newValue.OnTriggered += behaviour.OnEventTriggered;
    }

    private void OnEventTriggered(object sender, EventArgs e)
    {
        if (this.AssociatedObject != null)
            this.AssociatedObject.Navigate("http://www.google.com");    // <-- change this to the function you want to invoke
    }
}


文章来源: Execute a method on second control from the first control in WPF