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

我的问题的简化版本:我有两个简单的用户控件 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,但是如何确保集合正确更新苹果视图模型?



ibeautiful
浏览 157回答 1
1回答

陪伴而非守候

我会根据我从你的问题中了解到的给你我的想法。主窗口.xaml.cs&nbsp; &nbsp; public partial class MainWindow : Window{&nbsp; &nbsp; private AppleViewModel appleViewModel;&nbsp; &nbsp; public AppleViewModel AppleViewModel&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; get&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this.appleViewModel;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; set&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (this.appleViewModel != value)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.appleViewModel = value;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; private BananaViewModel bananaViewModel;&nbsp; &nbsp; public BananaViewModel BananaViewModel&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; get&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this.bananaViewModel;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; set&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (this.bananaViewModel != value)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.bananaViewModel = value;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; public MainWindow()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; InitializeComponent();&nbsp; &nbsp; &nbsp; &nbsp; this.AppleViewModel = new AppleViewModel();&nbsp; &nbsp; &nbsp; &nbsp; this.AppleViewModel.AppleID = "Apple001";&nbsp; &nbsp; &nbsp; &nbsp; this.AppleViewModel.Size = 10;&nbsp; &nbsp; &nbsp; &nbsp; this.BananaViewModel = new BananaViewModel();&nbsp; &nbsp; &nbsp; &nbsp; this.BananaViewModel.BananaID = "Banana001";&nbsp; &nbsp; &nbsp; &nbsp; this.BananaViewModel.Length = 10;&nbsp; &nbsp; &nbsp; &nbsp; apple.DataContext = this.AppleViewModel;&nbsp; &nbsp; &nbsp; &nbsp; banana.DataContext = this.BananaViewModel;&nbsp; &nbsp; &nbsp; &nbsp; ObservableCollection<int> sizes = new ObservableCollection<int>();&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < 10; i++)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sizes.Add(i);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; ListBox.ItemsSource = sizes;&nbsp; &nbsp; }&nbsp; &nbsp; private void ListBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (this.AppleViewModel.IsSelected)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.AppleViewModel.Size = (int)ListBox.SelectedItem;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if (this.BananaViewModel.IsSelected)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.BananaViewModel.Length = (int)ListBox.SelectedItem;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}主窗口.xaml&nbsp;<StackPanel Orientation="Vertical">&nbsp; &nbsp; &nbsp; &nbsp; <wpfApplication4:AppleControlxaml x:Name="apple"/>&nbsp; &nbsp; &nbsp; &nbsp; <wpfApplication4:BananaControl x:Name="banana"/>&nbsp; &nbsp; &nbsp; &nbsp; <ListBox SelectionChanged="ListBox_OnSelectionChanged" x:Name="ListBox">&nbsp; &nbsp; &nbsp; &nbsp; </ListBox>&nbsp; &nbsp; </StackPanel>您的水果虚拟机应该有一个名为 IsSelected 的新属性,例如:private bool isSelected;&nbsp; &nbsp; public bool IsSelected&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; get&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this.isSelected;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; set&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.isSelected = value;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OnPropertyChanged("IsSelected");&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }你的水果控制也应该有这个<CheckBox IsChecked="{Binding IsSelected}"/>如果您不想使用此复选框控件,请告诉我,我会尝试找到更准确的答案编辑以澄清您的编辑(xD):假设您已经使用其 Value 和 Description 属性创建了“SettingsVM”。现在您想在 ListBox 上显示您选择的水果设置。所以让我们走吧...每次你的水果改变时,你的 SettingsVM 的属性也必须改变才能显示正确的水果。在您的“banana1_MouseDown”或“apple1_MouseDown”中,您必须使用它们的属性初始化您的 SettingsVM,以便您可以创建一个方法来执行此操作。private void InitializeSettingsVM(int value, string description)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; //Same like you do when you initialize your Banana/AppleVM in your MainWindow initialize.&nbsp; &nbsp; &nbsp; this.SettingsVM.Value = value;&nbsp; &nbsp; &nbsp; this.SettingsVM.Description = description;&nbsp; &nbsp; }在您的banana1_MouseDown/apple1_MouseDown 中,您应该执行以下操作:private void banana1_MouseDown(whateveryouhavehere)&nbsp; &nbsp;{&nbsp; &nbsp; &nbsp;//Whatever you do here&nbsp; &nbsp; &nbsp;this.InitializeSettingsVM(this.BananaViewModel.Length,this.BananaViewModel.BananaID);&nbsp; &nbsp;}
打开App,查看更多内容
随时随地看视频慕课网APP