Pass UIElement to CommandParameter

自作多情 提交于 2019-12-13 14:27:51

问题


I'm using MVVM Light in my WPF application.

I created a class RedirectToUriCommandArgument.cs.

public class RedirectToUriCommandArgument : DependencyObject
{
    #region Properties

    public static readonly DependencyProperty PageProperty =
        DependencyProperty.Register(nameof(Page), typeof(object), typeof(RedirectToUriCommandArgument), new UIPropertyMetadata(null));

    public object Page
    {
        get => (object)GetValue(PageProperty);
        set => SetValue(PageProperty, value);
    }

    public string Uri { get; set; }

    #endregion

    #region Methods



    #endregion
}

In .xaml file, I used:

<Window x:Class="MainClient.Views.AppView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:v="clr-namespace:MainClient.Views"
        xmlns:vm="clr-namespace:MainClient.ViewModel"
        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        xmlns:commandArgument="clr-namespace:MainClient.Models.CommandArguments"
        xmlns:local="clr-namespace:MainClient"

        mc:Ignorable="d"
        WindowStartupLocation="CenterScreen"
        Height="350" Width="525">

    <Window.DataContext>
        <vm:AppViewModel x:Name="AppContext"></vm:AppViewModel>
    </Window.DataContext>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="32"/>
        </Grid.RowDefinitions>

        <Frame NavigationUIVisibility="Hidden" x:Name="PageFrame">
            <Frame.Content>
                <Page Name="MainPage"></Page>
            </Frame.Content>
        </Frame>
        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <Button>
                <Button.Content>
                    <TextBlock>Redirect to main view</TextBlock>
                </Button.Content>

                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <i:InvokeCommandAction Command="{Binding RedirectToViewRelayCommand}">
                            <i:InvokeCommandAction.CommandParameter>
                                <commandArgument:RedirectToUriCommandArgument Page="{Binding ElementName=PageFrame}" Uri="MainView.xaml"></commandArgument:RedirectToUriCommandArgument>
                            </i:InvokeCommandAction.CommandParameter>
                        </i:InvokeCommandAction>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Button>
        </StackPanel>
    </Grid>
</Window>

The Page property is always null.

Am I missing anything ?


回答1:


So I think the problem is, that as binding been initialized the UIElement is not created(null). Afterwords the binding is not notified, that the object is created.

Binding to the properties is easyer the object must implement INotifyPropertyChanged or DependencyObject take care about dependency properties.

To solve your issue you could set a Delay for Binding, say to 1000ms, then it will work. It's doubtful whether it is a right way.

<commandArgument:RedirectToUriCommandArgument Page="{Binding ElementName=PageFrame, Delay=1000}" Uri="MainView.xaml"></commandArgument:RedirectToUriCommandArgument>

The right way would be just set binding's source to the UIElement:

<commandArgument:RedirectToUriCommandArgument Page="{Binding Source={x:reference PageFrame}}" Uri="MainView.xaml"></commandArgument:RedirectToUriCommandArgument>


来源:https://stackoverflow.com/questions/51184181/pass-uielement-to-commandparameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!