每个View一个ViewModel?

时间:2013-02-07 10:17:52

标签: wpf xaml mvvm wpf-controls wpfdatagrid

我正在开发一个显示3个数据网格的UI应用程序,每个数据网格都相互依赖(selectedItem绑定)

这是我到目前为止所做的:

datagrid1有一个Model和一个ViewModel,

datagrid2有一个Model和一个ViewModel,

datagrid3有一个Model和一个ViewModel。

并且在每个DataContext属性中使用<Datagrid.DataContext>将所有三个ViewModel映射到View。为每个模型设置ViewModel的原因是,datagrid必须从数据库中选择各自表中的项目。

但是当我尝试在每个数据网格中设置SelectedItem时,我现在遇到了困难。 我正在粘贴一个数据网格的示例代码。像这样我也为其他两个datagrid创建了viewmodel。

XAML

<DataGrid DataContext="{Binding Path=HostData,NotifyOnTargetUpdated=True,Mode=OneWay}" 
AutoGenerateColumns="False" Name="hostDatagrid" Margin="171,32,235,230">
<Datagrid.DataContext>
<host:HostViewModel>
</Datagrid.DataContext>
<DataGrid.Columns>
<DataGridTextColumn Header="Host" Width="auto" Binding="{Binding HostID}" />
 <DataGridTextColumn Header="Status" Width="auto" Binding="{Binding HostStatus}"/> 
 </DataGrid.Columns>
</DataGrid>
 <DataGrid DataContext="{Binding Path=LogData,NotifyOnTargetUpdated=True,Mode=OneWay}"
 AutoGenerateColumns="False" Name="LogDatagrid" Margin="103,108,102,145">
<Datagrid.DataContext>
<host:LogViewModel>
</Datagrid.DataContext>
 <DataGrid.Columns>
<DataGridTextColumn Header="Host ID" Width="auto"  Binding="{Binding HostID}" />
<DataGridTextColumn Header="Logs" Width="auto"  Binding="{Binding LogID}" />
<DataGridTextColumn Header="Log Path" Width="auto"  Binding="{Binding LogPath}"/>
<DataGridTextColumn Header="Date" Width="auto"  Binding="{Binding Date}"/>
<DataGridTextColumn Header="Last Activity" Width="auto"  Binding="{Binding LastActivity}"/>

c# - 模型

 public LogFileModel()
 {

 }
 private int _hostID;
 public int HostID
 {
     get { return _hostID; }
     set { _hostID= value; OnpropertyChanged("HostID"); }
 }

 private string _logid;
 public string LogID
 {
     get { return _logid; }
     set { _logid= value; OnpropertyChanged("LogID"); }
 }

 private string _logpath;
 public string LogPath
 {
     get { return _logPath; }
     set { _logPath = value; OnpropertyChanged("LogPath"); }
 }

 private DateTime _date;
 public DateTime Date;
 {
     get { return _date; }
     set { _date= value; OnpropertyChanged("Date"); }
 }

 private bool _activity;
 public bool LastActivity
 {
     get { return _activity; }
     set { _activity= value; OnpropertyChanged("LastActivity"); }
 }

视图模型

  LogModel _myModel = new LogModel(); 
  private ObservableCollection<LogFileModel> _logFileData = new 
  ObservableCollection<LogFileModel>();  
  public  ObservableCollection<LogFileModel> LogFileData
 {
    get { return _logFileData; }
     set { _logFileData = value; OnPropertyChanged("LogFileData"); }
 }    public LogFileViewModel()
{
     initializeload();
     timer.Tick += new EventHandler(timer_Tick);
     timer.Interval = new TimeSpan(0, 0, 3);
     timer.Start();
 }

 ~LogFileViewModel()
 {
     Dispose(false);
 }

 protected virtual void Dispose(bool disposing)
 {
     if (!disposed)
     {
         if (disposing)
         {
             timer.Stop();
             timer.Tick -= new EventHandler(timer_Tick);
         }
         disposed = true;
     }
 }

 private void timer_Tick(object sender, EventArgs e)
 {
     try
     {
         LogFileData.Clear();
         initializeload();
     }
     catch (Exception ex)
     {
         timer.Stop();
         Console.WriteLine(ex.Message);

     }
 }

 private void initializeload()
 {
     try
     {
         DataTable table = _myModel.getData();

        for (int i = 0; i < table.Rows.Count; ++i)
             LogFileData.Add(new LogFileModel
             {
                HostID= Convert.ToInt32(table.Rows[i][0]),
                LogID = table.Rows[i][1].ToString(),
                LogPath = table.Rows[i][2].ToString(),
                Date = Convert.ToDateTime(table.Rows[i][3]),
                LastAcivity= table.Rows[i][4].ToString(),                   
             });
     }

     catch (Exception e)
     {
         Console.WriteLine(e.Message);
     }
 }
 public event PropertyChangedEventHandler PropertyChanged;

 private void OnPropertyChanged(string propertyname)
{
     var handler = PropertyChanged;
     if (handler != null)
         handler(this, new PropertyChangedEventArgs(propertyname));
 }

 public class LogModel
 {
     public DataTable getData()
     {
         DataTable ndt = new DataTable();
         SqlConnection sqlcon = new  SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);
         sqlcon.Open();
      //for this select statement only I have created separate ViewModel for the respective Model
         SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM [LocalDB].[dbo].[LogFiles]", sqlcon);
         da.Fill(ndt);
         da.Dispose();
         sqlcon.Close();
         return ndt;
     }
 } 
}

是否还有其他方法可以解决此问题,并为一个View创建一个ViewModel及其各自的datagrid - select语句?

1 个答案:

答案 0 :(得分:1)

您可以随意在不同的子视图中分割视图(例如用户控件)。 您也可以使用ViewModel做同样的事情。

您可以创建一个ViewModel,它代表整个视图,知道三个子视图模型......

public class MainViewModel : ViewModel
{
    private LogViewModel _SubLogViewModel = new LogViewModel();
    public LogViewModel SubLogViewModel
    {
        get
        {
            return _SubLogViewModel;
        }
        set
        {
            if (_SubLogViewModel != value)
            {
                _SubLogViewModel = value;
                OnpropertyChanged("SubLogViewModel");
            }
        }
    }

    private HostViewModel _SubHostViewModel = new HostViewModel();
    public HostViewModel SubHostViewModel
    {
        get
        {
            return _SubHostViewModel;
        }
        set
        {
            if (_SubHostViewModel != value)
            {
                _SubHostViewModel = value;
                OnpropertyChanged("SubHostViewModel");
            }
        }
    }

    private Host _SelectedHost;
    public Host SelectedHost
    {
        get
        {
            return _SelectedHost;
        }
        set
        {
            if (_SelectedHost!= value)
            {
                _SelectedHost= value;
                OnpropertyChanged("SelectedHost");
                if(this.SelectedHost != null && this.SubLogViewModel != null)
                {
                    this.SubLogViewModel.LoadLogFor(this.SelectedHost);
                }
            }
        }
    }
}

和XAML类似:

<Grid>
    <Grid.DataContext>
        <host:MainViewModel />
    </Grid.DataContext>

    <DataGrid Name="hostDataGrid" DataContext="{Binding SubHostModel}" SelectedItem="{Binding SelectedHost, Mode=TwoWay}">
        ...
    </DataGrid>

    <DataGrid Name="LogDatagrid" DataContext="{Binding SubLogModel}">

    </DataGrid>
</Grid>