【问题标题】:Display a User Control From Another User Control MVVM显示来自另一个用户控件 MVVM 的用户控件
【发布时间】:2015-05-04 09:09:35
【问题描述】:

我目前在我的视图模型中有这个方法,当用户点击网格行时触发:

    public ICommand EmailPopUpCmd { get; set; }
    private void EmailPopUp(object sender) {
        //ToDo: pdf viewer pop up
        var test = sender;
        var email = new EmailView { DataContext = new MailVM() };
        email.Visibility = Visibility.Visible;
    }

我要显示的用户控件如下所示:

<UserControl x:Class="Sybrin.UI.MailViewer.Views.EmailView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
         xmlns:fixed="clr-namespace:Telerik.Windows.Documents.Fixed;assembly=Telerik.Windows.Controls.FixedDocumentViewers"
         xmlns:converters="clr-namespace:Telerik.Windows.Documents.Converters;assembly=Telerik.Windows.Controls.FixedDocumentViewers"
         xmlns:local="clr-namespace:Sybrin.UI.MailViewer.Helpers"
         mc:Ignorable="d"
         d:DesignHeight="300" d:DesignWidth="300"
         DataContext="{Binding}">
<Grid>
    <Grid.Resources>
        <local:BoolToDisplayConverter x:Key="BoolToDisplayConverter"/>
    </Grid.Resources>
    <Grid.RowDefinitions>
        <RowDefinition Height="auto" />
        <RowDefinition Height="0.25*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="auto" />
    </Grid.RowDefinitions>
    <telerik:RadToolBar DataContext="{Binding ElementName=pdfViewer, Path=CommandDescriptors}">
        <telerik:RadToolBar.Resources>
            <converters:FixedDocumentViewerModeConverter x:Key="ModeConverter"/>
        </telerik:RadToolBar.Resources>
        <telerik:RadToggleButton IsChecked="{Binding FixedDocumentViewer.Mode, Mode=TwoWay, Converter={StaticResource ModeConverter}, ConverterParameter=Pan}"
                                 Margin="2"
                                 Padding="0"
                                 IsBackgroundVisible="False"
                                 HorizontalAlignment="Left"
                                 VerticalAlignment="Stretch"
                                 >
            <ToolTipService.ToolTip>
                <TextBlock Text="Pan" />
            </ToolTipService.ToolTip>
            <Image Source="pack://application:,,,/Telerik.Windows.Controls.FixedDocumentViewers;component/Images/hand-free.png"
                   Stretch="None" />
        </telerik:RadToggleButton>

        <telerik:RadToggleButton IsChecked="{Binding FixedDocumentViewer.Mode, Mode=TwoWay, Converter={StaticResource ModeConverter}, ConverterParameter=TextSelection}"
                                 Margin="2" Padding="0"
                                 IsBackgroundVisible="False"
                                 HorizontalAlignment="Left"
                                 VerticalAlignment="Stretch">
            <ToolTipService.ToolTip>
                <TextBlock Text="Text Selection" />
            </ToolTipService.ToolTip>
            <Image Source="pack://application:,,,/Telerik.Windows.Controls.FixedDocumentViewers;component/Images/text-selection.png"
                   Stretch="None" />
        </telerik:RadToggleButton>
    </telerik:RadToolBar>
    <telerik:RadPdfViewer x:Name="pdfEmailViewer"
                          Grid.Row="2"
                          DocumentSource="Sybrin.UI.MailViewer;Resources/TestPDF.pdf"/>
</Grid>

现在上述方法不显示我的用户控件。有什么想法为什么不呢?

【问题讨论】:

  • 你想在哪里显示这个用户控件?
  • 像一个弹出窗口(几乎像一个消息框)
  • 您只是在创建用户控件的实例并切换可见性。我看不到它被添加到任何地方的视图中。
  • 如何将它添加到视图中?

标签: c# wpf xaml mvvm user-controls


【解决方案1】:

理想情况下,您应该在其他窗口中打开此用户控件。

创建一个新窗口并将此用户控件添加到该视图(在 xaml 中)。然后在您的按钮命令处理程序中创建该窗口的一个实例,并且只需使用窗口的 Open() 方法就可以完成工作。

窗口 myWindow = new Window(); myWindow.Open();

虽然这不是一个很好的 MVVM 方式!

【讨论】:

    【解决方案2】:

    您可以将用户控件添加到您希望它显示的 xaml 视图中,并保持可见性绑定到属性。让值在开始时被折叠。当您希望控件可见时将其更改为可见。

    例如:

    <Grid>
       <EmailView Visibility= "{Binding ControlVisibility}" />
    </Grid>
    
    
    public ICommand EmailPopUpCmd { get; set; }
    private void EmailPopUp(object sender) {
        ControlVisibility = Visible;
     }
    
     private Visibility _controlVisibility = Collapsed;
    
     public Visibility ControlVisibility
     {
        get
        {
           return _controlVisibility;
        }
        set
        {
            _controlVisibility = value;
            OnPropertyChanged("ControlVisibility");
        }
     }
    

    确保您实施 INotifyPropertyChanged 以使可见性更改反映在 UI 中

    【讨论】:

    • 我试过这个,但我认为 Visibility.Collapsed 和 Visibility.Visible 应该通过转换器分配(因为我现在得到的错误是:Cannot create default converter to perform 'one-way' conversions between types 'UI.MailViewer.ViewModels.MailVM' and 'System.Windows.Visibility'. Consider using Converter property of Binding. BindingExpression:Path=; DataItem='MailVM' (HashCode=48386891); target element is 'MailViewerView' (Name=''); target property is 'Visibility' (type 'Visibility')
    • 您确定您在EmailView 上选择了正确的DataContext 吗?该错误似乎是因为您试图将MailVM 类型的属性绑定到可见性。
    • MailVM 是显示网格的视图模型(代码:public partial class EmailView : UserControl { public EmailView() { this.InitializeComponent(); this.DataContext = new MailVM(); //binds data context to the mail model view } }
    • 嗯...此错误表示绑定中的类型不匹配。如果可见性类型的属性绑定到控件的可见性,我想这不应该发生。
    • 另外请检查您是否使用过Mode = TwoWay
    猜你喜欢
    • 1970-01-01
    • 2015-08-03
    • 1970-01-01
    • 2015-10-04
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    相关资源
    最近更新 更多