2013-04-16 134 views
1

我一直在嘗試使用數據綁定和文件IO概念進行練習,爲此我編寫了這個簡單的應用程序,該應用程序讀取2列5行.csv文件並將內容顯示到一個WPF中的Listview,其功能是可以更改Listview中第二列的值(如2路綁定)。試圖獲取數據以顯示在我的列表視圖

我還沒有能夠獲得任何信息顯示在我的窗口。我只獲取我在MainWindow.xaml中定義的列標題,但沒有任何數據綁定正在工作。

這裏是我的視圖模型代碼和讀取文件

namespace WpfPreview 
{ 

public class LoadMovieData : BindableObject // My Data Context? 
{ 
    public string MovieName { get; set; } 
    private double year; public double Year { get { return year; } set { year = value; RaisePropertyChanged("Year"); } } 
} 


class ViewModel : BindableObject 
{ 
    private List<LoadMovieData> obsMovies = new List<LoadMovieData>(); 
    public List<LoadMovieData> ObsMovies 
    { 
     get { return obsMovies; } 
     set { obsMovies = value; RaisePropertyChanged("ObsMovies"); } 
    } 



    public void ReadFile() 
    { 

      string filepath = System.IO.Path.Combine("C:\\Users\\Param\\Desktop", "excel.csv"); // Get filepath 

      using (var csvReader = new StreamReader(filepath)) // using this filepath 
      { 
       csvReader.ReadLine();  // read first line (headers) 
       csvReader.ReadLine();  // read first line of row data 

       while (!csvReader.EndOfStream) // while not end of file 
       { 
        var words = csvReader.ReadLine().Split(',').ToList(); // read line to list of columns 
        var x = new LoadMovieData() // new instance of data class 
        { 
         MovieName = words[0], 
         Year = Convert.ToDouble(words[1]) 
        }; 

        ObsMovies.Add(x); // add instance of data class to list variable 

       } 
      } 

     } 

    } 
} 

我不知道如果我的條件是正確的。我正在嘗試遵循MVVM模式。我對窗口代碼隱藏是這樣的:

namespace WpfPreview 
{ 
/// <summary> 
/// Interaction logic for MainWindow.xaml 
/// </summary> 
public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     this.DataContext = new ViewModel(); 
    } 
} 
} 

,這裏是我的XAML部分:

<Window x:Class="WpfPreview.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:me="clr-namespace:WpfPreview" 
    Title="MainWindow" Height="350" Width="525"> 
<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto" /> 
    </Grid.RowDefinitions> 

    <Border Background="White"> 

     <ListView x:Name="MovieListView" ItemsSource="{Binding Path=ObsMovies}" VirtualizingStackPanel.IsVirtualizing="True" Background="Transparent"> 
      <ListView.View> 
       <GridView> 
        <GridViewColumn Header="Movie Name"> 
         <GridViewColumn.CellTemplate> 
          <DataTemplate> 
           <Grid> 
            <Grid.ColumnDefinitions> 
             <ColumnDefinition /> 
            </Grid.ColumnDefinitions> 
            <TextBlock Text="{Binding ObsMovies.MovieName}" /> 
           </Grid> 
          </DataTemplate> 
         </GridViewColumn.CellTemplate> 
        </GridViewColumn> 
        <GridViewColumn Header="Year" Width="60"> 
         <GridViewColumn.CellTemplate> 
          <DataTemplate> 
           <Grid> 
            <TextBlock Text="{Binding ObsMovies.Year}" /> 
           </Grid> 
          </DataTemplate> 
         </GridViewColumn.CellTemplate> 
        </GridViewColumn> 
       </GridView> 
      </ListView.View> 
     </ListView> 
    </Border> 
</Grid> 

我很新與文件IO與數據綁定/數據環境中工作。我確信在某個地方有一個明顯的錯誤,我想要做的事情可以以更簡單/更簡單的方式完成。請隨時給我建議重構我的代碼。

+0

你在哪裏調用'ReadFile'? –

+0

哦。我沒有在任何地方打過電話。我不確定我可以把MVVM放在哪裏。 –

+0

有時我所做的是向我的視圖模型添加一個加載方法,並從'WindowLoaded'事件的視圖中調用該方法。它應該打破模式。 – ywm

回答

2

我通常把我的數據加載代碼放在我的ViewModel構造函數中。另外,如果沒有訪問修飾符,您的ViewModel類是我相信的私人類,所以您將無法從課程外部調用任何內容。考慮製作它public

它看起來像你的obs電影列表應該是ObservableCollection。 obsMovies的值實現了PropertyChanged通知,但如果向其中添加項目,則該集合不會通知UI其集合已更改。

更改此:

private List<LoadMovieData> obsMovies = new List<LoadMovieData>(); 
public List<LoadMovieData> ObsMovies 
{ 
    get { return obsMovies; } 
    set { obsMovies = value; RaisePropertyChanged("ObsMovies"); } 
} 

要這樣:

private ObservableCollection<LoadMovieData> obsMovies = new ObservableCollection<LoadMovieData>(); 
public ObservableCollection<LoadMovieData> ObsMovies 
{ 
    get { return obsMovies; } 
    set { obsMovies = value; RaisePropertyChanged("ObsMovies"); } 
} 

你將不得不進口System.Collections.ObjectModel來利用它。

此外,它看起來像你的綁定可能不完全正確。請嘗試使用以下代碼:

<ListView.View> 
    <GridView> 
     <GridViewColumn Header="Movie Name"> 
      <GridViewColumn.CellTemplate> 
       <DataTemplate> 
        <Grid> 
         <TextBlock Text="{Binding ObsMovies.MovieName}" /> 
        </Grid> 
       </DataTemplate> 
      </GridViewColumn.CellTemplate> 
     </GridViewColumn> 
     <GridViewColumn Header="Year" Width="60"> 
      <GridViewColumn.CellTemplate> 
       <DataTemplate> 
        <Grid> 
         <TextBlock Text="{Binding ObsMovies.Year}" /> 
        </Grid> 
       </DataTemplate> 
      </GridViewColumn.CellTemplate> 
     </GridViewColumn> 
    </GridView> 
</ListView.View> 

上述綁定忽略了TextBlock綁定中的ObsMovies。由於每行DataContext是集合中的項目之一,因此不需要在綁定中引用集合。只需要在datacontext級別啓動綁定路徑(在這種情況下爲ObsMovies)。

最後,按照承諾,DataGrid中的樣本實現:

<DataGrid HorizontalAlignment="Left" VerticalAlignment="Top" ItemsSource="{Binding ObsMovies}"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Binding="{Binding Year}" ClipboardContentBinding="{x:Null}" Header="Year"/> 
     <DataGridTextColumn Binding="{Binding MovieName}" ClipboardContentBinding="{x:Null}" Header="Movie Name"/> 
    </DataGrid.Columns> 
</DataGrid> 

要有文本框,允許項目的編輯,在ListView例如,文本框取代的TextBlocks,併爲DataGrid,指定DataGridTemplateColumn並在模板中放置一個TextBox:

<DataGridTemplateColumn ClipboardContentBinding="{x:Null}"> 
    <DataGridTemplateColumn.CellTemplate> 
     <DataTemplate> 
      <TextBox Text="{Binding Property}"/> 
     </DataTemplate> 
    </DataGridTemplateColumn.CellTemplate> 
</DataGridTemplateColumn> 
+0

好吧,它現在有效。數據顯示在窗口中。但我無法編輯第二列單元格。我爲第二列設置了綁定模式爲2種方式,但我無法獲得要編輯的文本光標。我可能需要使用listview的數據網格Instad嗎? –

+1

您將兩個列的單元格模板設置爲TextBlock。這是一個只顯示控件。編輯時,您需要一個TextBox或類似的控件。您*可以*使用DataGrid,並且它會使列定義更容易(儘管不適用於編輯文本屬性)。我會在一兩分鐘內發佈一個例子。 – CodeWarrior

相關問題