Я несколько часов пытался заставить мой ListView работать с ObservableCollection. Однако не повезло. Я также прочитал некоторые посты здесь и там и пытаюсь соответствовать, и все еще бесполезно. Пожалуйста, дайте мне указатель на то, где это пошло не так.
По сути, я пытаюсь разделить логику от VM до класса Helper. И логика этого класса обновит данные, но виртуальная машина не знает об этом.
Моя проблема заключается в копировании файловой функции, статус задания не меняет представление данных. Я попытался Messenger.Default.Send (от помощника) и Messenger зарегистрироваться (в ВМ), чтобы принять изменения, все же не повезло.
Я использую MVVM Light, WPF, C #, кстати.
Вот мой код для модели.
public class MyFile : ViewModelBase
{
public string fullFileName { get; set; }
public string fileName { get; set; }
private string _jobStatus;
public string jobStatus
{
get { return _jobStatus; }
set { Set(ref _jobStatus, value); }
}
}
Вот мой код для Помощника.
class FileHelper
{
public List<MyFile> GetFileName(string dir)
{
List<MyFile> lstFiles = new List<MyFile>();
foreach (var file in (new DirectoryInfo(dir).GetFiles()))
{
if (file.Name.ToLower().Contains("xls") && !file.Name.Contains("~$"))
lstFiles.Add(new MyFile() { fullFileName = file.FullName, fileName = file.Name, jobStatus = "-" });
}
return lstFiles;
}
public bool CopyFiles(string destDir, List<MyFile> lstFiles)
{
try
{
int counter = 0;
foreach (MyFile f in lstFiles)
{
f.jobStatus = "Copying";
File.Copy(f.fullFileName, Path.Combine(destDir, f.fileName),true);
f.jobStatus = "Finished";
counter += 1;
Console.WriteLine("M: " + DateTime.Now.ToString("hh:mm:ss") + " " + counter);
Messenger.Default.Send(counter, "MODEL");
}
return true;
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
return false;
}
}
}
Вот мой код для ВМ.
public class MainViewModel : ViewModelBase
{
public ICommand CmdJob { get; private set; }
private ObservableCollection<MyFile> fileList;
public ObservableCollection<MyFile> FileList
{
get { return fileList; }
set { Set(ref fileList, value); }
}
private string counter;
public string Counter
{
get { return counter; }
set { Set(ref counter, value); }
}
public MainViewModel()
{
Messenger.Default.Register<int>(this, "MODEL", UpdateCounter);
CmdJob = new RelayCommand<object>(Action_Job);
Counter = "0";
}
private void UpdateCounter(int bgCounter)
{
Counter = bgCounter.ToString();
RaisePropertyChanged("FileList");
Console.WriteLine("VM: " + DateTime.Now.ToString("hh:mm:ss") + " " + Counter);
}
private void Action_Job(object tag)
{
if (tag == null || string.IsNullOrEmpty(tag.ToString()))
return;
switch (tag.ToString())
{
case "GET": GetFile(); break;
case "COPY": CopyFile(); break;
}
}
private void GetFile()
{
Counter = "0";
List<MyFile> myFs = new FileHelper().GetFileName(@"C:\Test\Original\");
FileList = new ObservableCollection<MyFile>(myFs);
}
private void CopyFile()
{
if (new FileHelper().CopyFiles(@"C:\Test\Destination\", fileList.ToList()))
Messenger.Default.Send("Files copying finished", "VM");
else
Messenger.Default.Send("Files copying failed", "VM");
}
}
А вот и мой XAML.
<ListView Grid.Row="0" Grid.Column="0" ItemsSource="{Binding FileList}" Margin="5,5,0,5" HorizontalAlignment="Left" VerticalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListView.View>
<GridView>
<GridViewColumn Header="File Name" Width="170" DisplayMemberBinding="{Binding fileName}" />
<GridViewColumn Header="Status" Width="170" DisplayMemberBinding="{Binding jobStatus}" >
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<StackPanel Grid.Row="0" Grid.Column="1" Orientation="Vertical">
<Button Content="Get file list" Tag="GET" Command="{Binding CmdJob}" CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Tag}" Width="80" Height="25" Margin="0,50,0,50"/>
<Button Content="Copy file" Tag="COPY" Command="{Binding CmdJob}" CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Tag}" Width="80" Height="25" />
<Label Content="{Binding Counter}" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" Height="25" FontWeight="Bold" Foreground="Red" Margin="0,50,0,0"/>
</StackPanel>
Я прочитал некоторые посты, в которых сказано, что для «изменений» ObservableCollection не будет отражать изменения в View. Итак, я следую решению этих сообщений (чтобы использовать уведомление об изменении в классе модели), не работает для меня.
Для меня мой индивидуальный файл имеет большой размер, поэтому я вижу, что на моей виртуальной машине нет обновлений.
Если вы тестируете файл небольшого размера, вы не увидите разницы.
Я пытался использовать метод Messenger, он также не обновлялся при просмотре, но моя виртуальная машина может принимать входящие сообщения без проблем.