【问题标题】:UWP UserControl with its own ViewModel as well as Dependency Properties using Template 10UWP UserControl 具有自己的 ViewModel 以及使用模板 10 的依赖属性
【发布时间】:2026-02-06 00:05:01
【问题描述】:

我正在使用模板 10 和 MVVM 创建 UWP 应用。我的要求是创建具有自己的依赖属性以及 ViewModel 的 UserControl。

我的要求:

  1. 在单击按钮时调用父 ViewModel 命令。
  2. 从 UserControl ViewModel 绑定 TexBlock 文本

我的用户控件如下所示:

  <vm:MyUserControl1  AddItem="{Binding MyCommand}"   Component="{Binding}"  RelativePanel.Below="abc" />

用户控制 XAML:

<StackPanel>
            <TextBlock Text="{x:Bind Component.Text, Mode=OneWay}"/>
            <Button x:Name="Button" Content="Click Me" Command="{x:Bind AddItem}">
            </Button>
</StackPanel>

这是代码后面的 UserControl 代码:

 public sealed partial class MyUserControl1 : UserControl
    {
        public MyUserControl1()
        {
            this.InitializeComponent();
            //   mygrid.DataContext = this;
            (this.Content as FrameworkElement).DataContext = this;
        }

        public static readonly DependencyProperty AddItemProperty =
          DependencyProperty.Register(
              "AddItem",
              typeof(ICommand),
              typeof(MyUserControl1), new PropertyMetadata(null));

        public ICommand AddItem
        {
            get { return (ICommand)GetValue(AddItemProperty); }
            set { SetValue(AddItemProperty, value); }
        }

        public static readonly DependencyProperty ComponentProperty = DependencyProperty.Register("Component",typeof(MyViewModel),typeof(MyUserControl1),new PropertyMetadata(null));

        public MyViewModel Component
        {
            get { return (MyViewModel)GetValue(ComponentProperty); }
            set { SetValue(ComponentProperty, value); }
        }

    }

UserControl 视图模型:

public class MyViewModel:ViewModelBase
    {
        public MyViewModel()
        {

        }
        public string Text => "ABC";
    }

父视图模型:

  public class SettingsPartViewModel : ViewModelBase
  {
        DelegateCommand _MyCommand;

        public DelegateCommand MyCommand
            => _MyCommand ?? (_MyCommand = new DelegateCommand(async () =>
            {
                await Task.Run(() => {
                  ///Some Code  
                });
            }));
     }

每当我运行代码时,都会出现以下错误:

 Unable to cast object of type 'WindowsApp2.ViewModels.SettingsPartViewModel' to type 'WindowsApp2.ViewModels.MyViewModel'. 

这里出了什么问题?

【问题讨论】:

    标签: mvvm data-binding user-controls uwp template10


    【解决方案1】:

    我认为你在这里出错了Component="{Binding}"。您直接将组件设置为父视图的 DataContext 即 WindowsApp2.ViewModels.SettingsPartViewModel 而不是 WindowsApp2.ViewModels.MyViewModel

    要使其正常工作,您需要在您的SettingsPartViewModel 中创建MyViewModel 的实例并将其绑定到Component

    试试下面的示例:

    在 SettingsPartViewModel 中:

    private MyViewModel myViewModelInstance = new MyViewModel();
    
    public MyViewModel MyViewModelInstance
    {
        get { return myViewModelInstance; }
        set { myViewModelInstance = value; //Raise NotifyPropertyChanged }
    }
    

    在 SettingsPart.xaml 中:

    <vm:MyUserControl1  AddItem="{Binding MyCommand}"   Component="{Binding MyViewModelInstance}"  RelativePanel.Below="abc" />
    

    【讨论】:

    • 非常感谢您的解决方案。它现在按预期工作。但现在我面临的唯一问题是如果我更改 MyViewModel 属性值而不反映在 UI 上。我试过做 Component="{Binding MyViewModelInstance,Mode=OneWay}" 但仍然没有运气。你能帮忙吗
    • 没有看到你的代码,我帮不了你。试试Mode=TwoWay,同时检查你是否正确实现了INotifyPropertyChanged接口。
    • 完成。将组件属性模式设置为 OneWay 解决了问题 Text="{x:Bind Component.Text,Mode=OneWay}"。一切都像魅力一样运作。谢谢哥们!