您的位置:首页 > 其它

WPF中的MVVM模式:How to render dynamic controls on the fly in MvvM pattern

2010-07-29 11:09 483 查看
出处:http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/1be16a18-ab9c-4381-952a-4aa642f159e1

For MVVM, we usually use ViewModel to get raw data from data source and create public properties for raw data to enable vm binding to update the view; I’d create new controls on the fly in view code behind (for example, in MainWindow class) because it is a view thing. Let’s take a look at the MVVM example below to see how to use vm binding to update view, the WatchListViewModel gets raw Quote date from QuoteSource, and it has public properties Quotes and LastSymbol to enable the vm binding for Quote data.

Example:

<Window x:Class="MVVMSample.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="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="Quote Name: "/>
<TextBox Text="{Binding Path=Symbol, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Background="LightBlue"/>
<TextBlock Grid.Row="1" Text="Last Quote Name: "/>
<TextBlock Text="{Binding Path=LastSymbol}" Grid.Row="1" Grid.Column="1" Background="LightCoral"/>
<Button Grid.Row="2" Content="Subscribe" Command="{Binding SubscribeCommand}" />
<ListView Grid.Row="3" Grid.ColumnSpan="2" Background="LightYellow" ItemsSource="{Binding Quotes}">
<ListView.View>
<GridView>
<GridViewColumn Header="Symbol" DisplayMemberBinding="{Binding Path=Symbol}" Width="80" />
<GridViewColumn Header="Price" DisplayMemberBinding="{Binding Path=Price}" Width="80"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>

using System;
using System.Collections.ObjectModel;
using System.Threading;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;

namespace MVVMSample
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new WatchListViewModel(new QuoteSource());
}
}
public class WatchListViewModel : DependencyObject
{
private ISource source;
private Dispatcher currentDispatcher = Dispatcher.CurrentDispatcher;
public WatchListViewModel(ISource source)
{
this.source = source;
this.Quotes = new ObservableCollection<Quote>();
this.source.QuoteArrived += new Action<Quote>(source_QuoteArrived);
this.SubscribeCommand = new SubscribeCommnand(this);
}
void source_QuoteArrived(Quote quote)
{
Action action = () => Quotes.Add(quote);
currentDispatcher.BeginInvoke(action);
}
public string Symbol { set; get; }
public string LastSymbol
{
get { return (string)GetValue(LastSymbolProperty); }
set { SetValue(LastSymbolProperty, value); }
}
public static readonly DependencyProperty LastSymbolProperty =
DependencyProperty.Register("LastSymbol", typeof(string), typeof(WatchListViewModel), new UIPropertyMetadata(""));
public ObservableCollection<Quote> Quotes { set; get; }
public ICommand SubscribeCommand { set; get; }
public void Subscribe()
{
source.Subscribe(Symbol);
LastSymbol = Symbol;
}
}
public class SubscribeCommnand : ICommand
{
private WatchListViewModel vm;
public SubscribeCommnand(WatchListViewModel vm) { this.vm = vm; }
public bool CanExecute(object parameter) { return !String.IsNullOrEmpty(vm.Symbol); }
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter) { vm.Subscribe(); }
}
public interface ISource
{
void Subscribe(string symbol);
event Action<Quote> QuoteArrived;
}
public class Quote
{
public string Symbol { set; get; }
public double Price { set; get; }
}
public class QuoteSource : ISource
{
static double price = 10;
private string symbol;
public void Subscribe(string symbol)
{
this.symbol = symbol;
Thread workerThread = new Thread(new ThreadStart(GenerateQuote)) { IsBackground = true, Priority = ThreadPriority.Normal };
workerThread.Start();
}
private void GenerateQuote()
{
Thread.Sleep(TimeSpan.FromSeconds(1)); // Time consuming work
if (!String.IsNullOrEmpty(symbol) && QuoteArrived != null)
QuoteArrived(new Quote { Symbol = symbol, Price = price++ });
}
public event Action<Quote> QuoteArrived;
}
}

William
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐