简体   繁体   English

使用ICommand和MVVM在UWP中显示ContentDialog

[英]Display a ContentDialog in UWP, using an ICommand with MVVM

I'm creating a UWP application where I want a user to be able to upload photos. 我正在创建一个UWP应用程序,我希望用户能够上传照片。 I have a ContentDialog with a Button and two TextBoxes . 我有一个带ButtonContentDialog和两个TextBoxes The ContentDialog should pop up when the user presses the "Upload Photo" Button . 当用户按下“上传照片” Button时, ContentDialog应该弹出。 How can I do this using MVVM? 如何使用MVVM执行此操作?

The logic for finding the file and posting the files to the database are already done, only the UI is remaining. 查找文件并将文件发布到数据库的逻辑已经完成,仅保留UI。

Here is my XAML: 这是我的XAML:

<!-- Content -->
<Button Content="Upload a photo to gallery" Margin="40,0,0,0" x:Name="UploadPhotoButton" Command="{x:Bind MyProfileViewModel.OpenContentDialog}"/>
<!-- More content -->

<!-- This is the ContentDialog I want to display when the user presses the button above -->
<ContentDialog x:Name="UploadPhotoContentDialog"
    PrimaryButtonText="Upload" IsPrimaryButtonEnabled="{Binding IsValid}"
    SecondaryButtonText="Cancel" IsSecondaryButtonEnabled="True">
    <ContentDialog.TitleTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <SymbolIcon Symbol="BrowsePhotos"/>
                <TextBlock Margin="10,0,0,0" Text="Upload photo "/>
            </StackPanel>
        </DataTemplate>
    </ContentDialog.TitleTemplate>

    <Grid Padding="10" Margin="0,10,0,0">
        <Grid.RowDefinitions>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>

        <TextBlock Text="Photo Title:" VerticalAlignment="Center"/>
        <TextBox Text="{Binding PhotoTitle, Mode=TwoWay}" PlaceholderText="Example: Fun in the sun" Grid.Column="1"/>
        <TextBlock Text="Photo Caption:" Grid.Row="1" VerticalAlignment="Center"/>
        <TextBox Text="{Binding PhotoDesc, Mode=TwoWay}" PlaceholderText="Example: Don't you just love the beach" Grid.Row="1" Grid.Column="1"/>
        <Button Content="Browse files..." Grid.Column="0" Grid.Row="2" Margin="0,20,0,0" Command="{x:Bind MyProfileViewModel.FindFile}"/>
        <TextBox Text="{Binding FileName, Mode=TwoWay}" Grid.Row="2" Grid.Column="1" Margin="10,20,0,0" FontSize="12" Height="32" IsReadOnly="True" />
    </Grid>
</ContentDialog>

So far, here is my C# file (MyProfileViewModel): 到目前为止,这是我的C#文件(MyProfileViewModel):

public ICommand OpenContentDialog => new CommandHandler(async () => {
    //  What to put in here to find the ContentDialog, then display it?
});

One of the methods may bo to pass the ContentDialog as CommandParameter . 其中一种方法可以传递ContentDialog作为CommandParameter For example like this: 例如这样:

<Button Content="Upload a photo to gallery" Margin="40,0,0,0" x:Name="UploadPhotoButton" Command="{x:Bind MyProfileViewModel.OpenContentDialog}" CommandParameter="{Binding ElementName=UploadPhotoContentDialog}"/>

and invokation: 和发票:

public RelayCommand OpenContentDialog => new RelayCommand(async (dialog) => { (dialog as ContentDialog).ShowAsync(); });

I found the answer to my problem. 我找到了解决我问题的方法。 I created a new Class that implements ICommand called RelayCommand, with input from Romasz . 我使用Romasz的输入创建了一个实现ICommand的新Class称为RelayCommand)

His ViewModel and binding in the XAML was correct. 他在XAML中的ViewModel和绑定是正确的。 I just had to adjust my ICommands. 我只需要调整ICommands。 Here is my RelayCommand Class 这是我的RelayCommand Class

public class RelayCommand : ICommand {
    private readonly Action<object> _execute;
    private readonly Func<bool> _canExecute;

    public event EventHandler CanExecuteChanged;

    public RelayCommand(Action<object> execute)
        : this(execute, null) {
    }

    public RelayCommand(Action<object> execute, Func<bool> canExecute) {
        _execute = execute ?? throw new ArgumentNullException("execute");
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter) {
        return _canExecute == null ? true : _canExecute();
    }

    public void Execute(object parameter) {
        _execute(parameter);
    }

    public void RaiseCanExecuteChanged() {
        CanExecuteChanged?.Invoke(this, EventArgs.Empty);
    }
}

I had to add <object> for the Action, since the ViewModel logic kept complaining that Action did not take a parameter. 我必须为Action添加<object> ,因为ViewModel逻辑一直抱怨Action没有参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM