为了账号安全,请及时绑定邮箱和手机立即绑定

遵循 MVVM 模式,如何创建一个“设置”函数来设置其他用户控件中的数据绑定项值?

遵循 MVVM 模式,如何创建一个“设置”函数来设置其他用户控件中的数据绑定项值?

C#
ibeautiful 2021-06-01 09:53:07
我的问题的简化版本:我有两个简单的用户控件 Apple 和 Banana(视图),它们各自包含 2 个属性的相应视图模型。我还有一个 ListBox 作为 Apple 和 Banana 属性的“设置”。苹果:<UserControl>      <StackPanel Orientation="Horizontal">          <TextBlock Margin="0,0,20,0" Text="{Binding AppleID}"/>          <TextBlock Text="{Binding Size}"/>      </StackPanel>  </UserControl>  香蕉:<UserControl>      <StackPanel Orientation="Horizontal">        <TextBlock Margin="0,0,20,0"  Text="{Binding BananaID}"/>        <TextBlock Text="{Binding Length}"/>    </StackPanel></UserControl>  苹果虚拟机:public class AppleViewModel : Notifier{    private string appleID;    public string AppleID    {        get => appleID; set        {            appleID = value;            OnPropertyChanged("AppleID");        }    }    private int size;    public int Size    {        get => size; set        {            size = value;            OnPropertyChanged("Size");        }    }}香蕉虚拟机:public class BananaViewModel : Notifier{    private string bananaID;    public string BananaID    {        get => bananaID; set        {            bananaID = value;            OnPropertyChanged("BananaID");        }    }    private int length;    public int Length    {        get => length; set        {            length = value;            OnPropertyChanged("Length");        }    }}主窗口如下所示:<Window>    <StackPanel Orientation="Vertical">        <local:AppleControlxaml x:Name="apple"/>        <local:BananaControl x:Name="banana"/>        <ListBox>        </ListBox>    </StackPanel></Window>为了更快地设置,我在主窗口后面的代码中分配了 DataContext。在实际情况中,我使用了窗口视图模型。现在我希望 listBox 控件显示并允许用户设置正在聚焦的用户控件的属性值。典型的交互是 Select/Mousedown Apple user control area -> Change length in listbox -> See that apple user control values changed。如果用户选择/鼠标按下 Banana 用户控件,他/她应该也可以这样做。问题是:如何使用 MVVM 和数据绑定来实现此设置功能?我尝试为要绑定到的视图框的 ItemsSource 创建一个 ObservableCollection,但是如何确保集合正确更新苹果视图模型?
查看完整描述

1 回答

?
陪伴而非守候

TA贡献1757条经验 获得超8个赞

我会根据我从你的问题中了解到的给你我的想法。


主窗口.xaml.cs


    public partial class MainWindow : Window

{

    private AppleViewModel appleViewModel;

    public AppleViewModel AppleViewModel

    {

        get

        {

            return this.appleViewModel;

        }

        set

        {

            if (this.appleViewModel != value)

            {

                this.appleViewModel = value;

            }

        }

    }


    private BananaViewModel bananaViewModel;

    public BananaViewModel BananaViewModel

    {

        get

        {

            return this.bananaViewModel;

        }

        set

        {

            if (this.bananaViewModel != value)

            {

                this.bananaViewModel = value;

            }

        }

    }



    public MainWindow()

    {

        InitializeComponent();


        this.AppleViewModel = new AppleViewModel();

        this.AppleViewModel.AppleID = "Apple001";

        this.AppleViewModel.Size = 10;


        this.BananaViewModel = new BananaViewModel();

        this.BananaViewModel.BananaID = "Banana001";

        this.BananaViewModel.Length = 10;


        apple.DataContext = this.AppleViewModel;


        banana.DataContext = this.BananaViewModel;


        ObservableCollection<int> sizes = new ObservableCollection<int>();

        for (int i = 0; i < 10; i++)

        {

            sizes.Add(i);

        }


        ListBox.ItemsSource = sizes;


    }


    private void ListBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)

    {

        if (this.AppleViewModel.IsSelected)

        {

            this.AppleViewModel.Size = (int)ListBox.SelectedItem;

        }

        if (this.BananaViewModel.IsSelected)

        {

            this.BananaViewModel.Length = (int)ListBox.SelectedItem;

        }

    }

}

主窗口.xaml


 <StackPanel Orientation="Vertical">

        <wpfApplication4:AppleControlxaml x:Name="apple"/>

        <wpfApplication4:BananaControl x:Name="banana"/>

        <ListBox SelectionChanged="ListBox_OnSelectionChanged" x:Name="ListBox">

        </ListBox>

    </StackPanel>

您的水果虚拟机应该有一个名为 IsSelected 的新属性,例如:


private bool isSelected;

    public bool IsSelected

    {

        get

        {

            return this.isSelected;


        }

        set

        {

            this.isSelected = value;

            OnPropertyChanged("IsSelected");

        }

    }

你的水果控制也应该有这个


<CheckBox IsChecked="{Binding IsSelected}"/>

如果您不想使用此复选框控件,请告诉我,我会尝试找到更准确的答案


编辑以澄清您的编辑(xD):


假设您已经使用其 Value 和 Description 属性创建了“SettingsVM”。现在您想在 ListBox 上显示您选择的水果设置。所以让我们走吧...每次你的水果改变时,你的 SettingsVM 的属性也必须改变才能显示正确的水果。在您的“banana1_MouseDown”或“apple1_MouseDown”中,您必须使用它们的属性初始化您的 SettingsVM,以便您可以创建一个方法来执行此操作。


private void InitializeSettingsVM(int value, string description)

    {

      //Same like you do when you initialize your Banana/AppleVM in your MainWindow initialize.

      this.SettingsVM.Value = value;

      this.SettingsVM.Description = description;

    }

在您的banana1_MouseDown/apple1_MouseDown 中,您应该执行以下操作:


private void banana1_MouseDown(whateveryouhavehere)

   {

     //Whatever you do here

     this.InitializeSettingsVM(this.BananaViewModel.Length,this.BananaViewModel.BananaID);

   }


查看完整回答
反对 回复 2021-06-05
  • 1 回答
  • 0 关注
  • 141 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信