gpt4 book ai didi

带有 MVVM ViewModel 的 WPF 用户控件数据绑定(bind)

转载 作者:行者123 更新时间:2023-12-03 10:14:05 26 4
gpt4 key购买 nike

我在这方面花了很长时间,所以寻求帮助。

使用 mvvm light 与用户控件进行简单数据绑定(bind)不起作用。

我做了以下事情。

  • 使用 VS 2015 创建了一个 MvvmLight (WPF451) 项目并将其命名为 WpfDataBindingUserControlT1
  • 添加了一个 UserControl 并将其重命名为 SimpleUserControl.xaml
  • 在 SimpleUserControl.xaml 中的网格中添加了一些标签作为子项(包含在堆栈面板中)(所有代码在下面给出)
  • 在 SimpleUserControl.xaml(SimpleUserControl.cs) 后面的代码中添加了一个依赖属性,以便这些属性可以帮助我进行数据绑定(bind)。

  • 数据绑定(bind)根本不起作用。我已经拉了一半的头发,所以请帮忙。我想我在这方面很简单。

    代码如下。
  • MainWindows.xaml
    <Window x:Class="WpfDataBindingUserControlT1.MainWindow"
    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:ignore="http://www.galasoft.ch/ignore"
    xmlns:local="clr-namespace:WpfDataBindingUserControlT1"
    mc:Ignorable="d ignore"
    Height="400"
    Width="300"
    Title="MVVM Light Application"
    DataContext="{Binding Main, Source={StaticResource Locator}}">

    <Window.Resources>
    <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="Skins/MainSkin.xaml" />
    </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
    </Window.Resources>

    <Grid x:Name="LayoutRoot">

    <TextBlock FontSize="36"
    FontWeight="Bold"
    Foreground="Purple"
    Text="{Binding WelcomeTitle}"
    VerticalAlignment="Center"
    HorizontalAlignment="Center"
    TextWrapping="Wrap" />

    <local:SimpleUserControl DataContext="{Binding RelativeSource={RelativeSource Self}}" CellValue="{Binding WelcomeTitle}" />
    </Grid>
    </Window>
  • MainWindow.cs(我没有更改此文件中的任何内容。)
    using System.Windows;
    using WpfDataBindingUserControlT1.ViewModel;

    namespace WpfDataBindingUserControlT1
    {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
    /// <summary>
    /// Initializes a new instance of the MainWindow class.
    /// </summary>
    public MainWindow()
    {
    InitializeComponent();
    Closing += (s, e) => ViewModelLocator.Cleanup();
    }
    }
    }
  • 简单用户控件.xaml
    <UserControl x:Class="WpfDataBindingUserControlT1.SimpleUserControl"
    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:local="clr-namespace:WpfDataBindingUserControlT1"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
    <StackPanel>
    <Label Content="This Prints" />
    <Label Name="MyLable" Content="{Binding Path=CellValue}"></Label>
    <Label Content="This also Prints" />
    </StackPanel>
    </Grid>
    </UserControl>
  • SimpleUserControl.cs(添加了依赖项)
    using System.Windows;
    using System.Windows.Controls;

    namespace WpfDataBindingUserControlT1
    {
    /// <summary>
    /// Interaction logic for SimpleUserControl.xaml
    /// </summary>
    public partial class SimpleUserControl : UserControl
    {
    public string CellValue
    {
    get { return (string)GetValue(CellValueProperty); }
    set { SetValue(CellValueProperty, value); }
    }

    public static readonly DependencyProperty CellValueProperty =
    DependencyProperty.Register("CellValue", typeof(string), typeof(SimpleUserControl), new FrameworkPropertyMetadata
    {
    BindsTwoWayByDefault = true,
    });

    public SimpleUserControl()
    {
    InitializeComponent();
    }
    }
    }
  • MainViewModel.cs(我没有改变任何东西)
    using GalaSoft.MvvmLight;
    using WpfDataBindingUserControlT1.Model;

    namespace WpfDataBindingUserControlT1.ViewModel
    {
    /// <summary>
    /// This class contains properties that the main View can data bind to.
    /// <para>
    /// See http://www.mvvmlight.net
    /// </para>
    /// </summary>
    public class MainViewModel : ViewModelBase
    {
    private readonly IDataService _dataService;

    /// <summary>
    /// The <see cref="WelcomeTitle" /> property's name.
    /// </summary>
    public const string WelcomeTitlePropertyName = "WelcomeTitle";

    private string _welcomeTitle = string.Empty;

    /// <summary>
    /// Gets the WelcomeTitle property.
    /// Changes to that property's value raise the PropertyChanged event.
    /// </summary>
    public string WelcomeTitle
    {
    get
    {
    return _welcomeTitle;
    }
    set
    {
    Set(ref _welcomeTitle, value);
    }
    }

    /// <summary>
    /// Initializes a new instance of the MainViewModel class.
    /// </summary>
    public MainViewModel(IDataService dataService)
    {
    _dataService = dataService;
    _dataService.GetData(
    (item, error) =>
    {
    if (error != null)
    {
    // Report error here
    return;
    }

    WelcomeTitle = item.Title;
    });
    }

    ////public override void Cleanup()
    ////{
    //// // Clean up if needed

    //// base.Cleanup();
    ////}
    }
    }
  • ViewModelLocator.cs(我也没有更改任何内容。)
    /*
    In App.xaml:
    <Application.Resources>
    <vm:ViewModelLocatorTemplate xmlns:vm="clr-namespace:WpfDataBindingUserControlT1.ViewModel"
    x:Key="Locator" />
    </Application.Resources>

    In the View:
    DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}"
    */

    using GalaSoft.MvvmLight;
    using GalaSoft.MvvmLight.Ioc;
    using Microsoft.Practices.ServiceLocation;
    using WpfDataBindingUserControlT1.Model;

    namespace WpfDataBindingUserControlT1.ViewModel
    {
    /// <summary>
    /// This class contains static references to all the view models in the
    /// application and provides an entry point for the bindings.
    /// <para>
    /// See http://www.mvvmlight.net
    /// </para>
    /// </summary>
    public class ViewModelLocator
    {
    static ViewModelLocator()
    {
    ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

    if (ViewModelBase.IsInDesignModeStatic)
    {
    SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
    }
    else
    {
    SimpleIoc.Default.Register<IDataService, DataService>();
    }

    SimpleIoc.Default.Register<MainViewModel>();
    }

    /// <summary>
    /// Gets the Main property.
    /// </summary>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
    "CA1822:MarkMembersAsStatic",
    Justification = "This non-static member is needed for data binding purposes.")]
    public MainViewModel Main
    {
    get
    {
    return ServiceLocator.Current.GetInstance<MainViewModel>();
    }
    }

    /// <summary>
    /// Cleans up all the resources.
    /// </summary>
    public static void Cleanup()
    {
    }
    }
    }
  • 最佳答案

    将此行添加到您的 SimpleUserControl.cs构造函数

    public SimpleUserControl()
    {
    InitializeComponent();

    (this.Content as FrameworkElement).DataContext = this;
    }

    您基本上是在设置 DataContext UserControl 中的第一个元素.

    Jerry Nixon 对此有一篇很棒的文章 here

    更新
    忘记添加摆脱 RelativeSource例如
    <local:SimpleUserControl CellValue="{Binding WelcomeTitle}" />

    关于带有 MVVM ViewModel 的 WPF 用户控件数据绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37026023/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com