繁体   English   中英

在mainviewmodel上寻找有关MVVM文本块绑定的指导

[英]Looking for guidance with MVVM textblock binding on mainviewmodel

我有一个与股票相关的应用程序。

它的外观有点像Josh Smith的MVVM演示应用程序,但有一些附加功能。

我有一个名为ShortQuote.cs的数据模型,该数据模型具有一个ViewModel ShortQuoteViewModel ,但现在不使用ShortQuoteViewModel。

我有一个ShortQuoteRepository ,它创建一个从XML数据文件中ShortQuote类型的对象的列表。 当用户单击主窗口左窗格上的命令时, ShortQuoteRepository列表将显示在选项卡中。

我在MainWindow上有一个组合框,其中有一个股票代码列表。 当用户选择这些股票代码之一时,我想从ShortQuoteRepository中获取一个StockQuote对象(如果该股票代码存在),并将其内容显示在MainWindow视图顶部的TextBlocks中。

我可以使它起作用的唯一方法是在MainWindowViewModel上公开“新”属性,这些属性是ShortQuote数据模型上属性的镜像,然后一旦我从ShortQuoteRepository获得ShortQuote对象,便设置MainWindowViewModel的“ new”属性等于从检索到的对象中得到的值。 我将TextBlock绑定到MainWindowViewModel的“新”属性,并且可以正常工作。

我感觉这是一个“ hack”,并且有一种“更好”的方法来完成此任务,而不必在MainWindowViewModel上创建“ new”属性,并且正在寻求一些指导和建议以进一步实现此目的。仅使用XAML或XAML和MainWindowViewModel代码的组合的简单方法,而无需创建这些“新”属性。

谁能帮我?

还可以将ShortQuote设置为ViewModel(如果使用的是MVVM Light,则至少要设置一个ObservableObject)。 然后,可以将SelectedItem绑定到视图ShortQuote上的ShortQuote属性(将其标记为TwoWay)。 然后,您的视图可以根据需要引用SelectedItem

将此添加到ShortQuoteViewModel.cs

private ShortQuote _selectedQuote;

public ShortQuote SelectedQuote
{    
     get { return _selectedQuote; }
     set
     {
          if(value != _selectedQuote)
          {
               _selectedQuote = value;
               RaisePropertyChanged("SelectedQuote");
          }
      }
}

XAML:

<ListBox ItemsSource="{Binding Quotes}" SelectedItem={Binding SelectedQuote, Mode=TwoWay}"/>

<TextBlock Text="{Binding SelectedQuote.Ticker}"/>

您还必须更改您的ShortQuote类(可能在ShortQuote.cs )以实现INotifyPropertyChanged ,方法是通过显式实现INPC或从ViewModel或ObservableObject继承(如果使用MVVM Light)。您没有指定,但是很流行,如果您不使用它,则应考虑这样做)。

编辑这是一个工作示例:

XAML:

<Window x:Class="StockQuoteExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="24"/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <TextBlock>
            <Run Text="Company Name: "/>
            <Run Text="{Binding SelectedTicker.Ticker}"/>
            <Run Text="  Symbol:  "/>
            <Run Text="{Binding SelectedTicker.StockName}"/>
            <Run Text="  Tick Price:  "/>
            <Run Text="{Binding SelectedTicker.TickPrice}"/>
        </TextBlock>

        <ListBox Grid.Row="1" Margin="10" ItemsSource="{Binding StockQuotes}" SelectedItem="{Binding SelectedTicker, Mode=TwoWay}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Width="120" Text="{Binding Ticker}"/>
                        <TextBlock Width="120" Margin="5,0,5,0" Text="{Binding StockName}"/>
                        <TextBlock Width="120" Text="{Binding TickPrice}"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

代码隐藏:

using System.Windows;
using StockQuoteExample.ViewModel;

namespace StockQuoteExample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            this.DataContext = new StockQuoteViewModel();
        }
    }
}

视图模型:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using StockQuoteExample.DataModel;

namespace StockQuoteExample.ViewModel
{
    class StockQuoteViewModel : INotifyPropertyChanged
    {

        public ObservableCollection<StockQuote> StockQuotes { get; set; }

        private StockQuote _selectedTicker;

        public StockQuote SelectedTicker
        {
            get { return _selectedTicker; }
            set
            {
                if (value != _selectedTicker)
                {
                    _selectedTicker = value;
                    OnPropertyChanged("SelectedTicker");
                }
            }
        }


        public StockQuoteViewModel()
        {
            StockQuotes = new ObservableCollection<StockQuote>()
                              {
                                  new StockQuote() {StockName = "Microsoft", TickPrice = 150m, Ticker = "MSFT"},
                                  new StockQuote() {StockName = "Apple", TickPrice = 600m, Ticker = "AAPL"}
                              };
        }




        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

    }
}

资料模型:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;

namespace StockQuoteExample.DataModel
{
    public class StockQuote : INotifyPropertyChanged
    {

        private string _ticker;

        public string Ticker
        {
            get { return _ticker; }
            set
            {
                if (value != _ticker)
                {
                    _ticker = value;
                    OnPropertyChanged("Ticker");
                }
            }
        }

        private string _stockName;

        public string StockName
        {
            get { return _stockName; }
            set
            {
                if (value != _stockName)
                {
                    _stockName = value;
                    OnPropertyChanged("StockName");
                }
            }
        }

        private decimal _tickPrice;

        public decimal TickPrice
        {
            get { return _tickPrice; }
            set
            {
                if (value != _tickPrice)
                {
                    _tickPrice = value;
                    OnPropertyChanged("TickPrice");
                }
            }
        }




        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM