簡體   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