1

My WPF ListViewПроблемы с привязкой к ObservableCollection внутри объекта к ListView

 <ListView Name="lstTasks" ItemContainerStyle="{StaticResource itemstyle}" ItemsSource="{Binding ElementName=TaskFile,Path=obscollFiles}" SelectionMode="Single"> 
      <ListView.View> 
       <GridView> 
        <GridViewColumn Header="Id" DisplayMemberBinding="{Binding TaskId}" /> 
        <GridViewColumn Header="Datum" DisplayMemberBinding="{Binding TaskDate,StringFormat={}{0:dd.MM.yyyy}}" /> 
        <GridViewColumn Header="Startzeit" DisplayMemberBinding="{Binding TaskStartTime,StringFormat=t}" /> 
        <GridViewColumn Header="Endzeit" DisplayMemberBinding="{Binding TaskEndTime,StringFormat=t}" /> 
        <GridViewColumn Header="Dauer" DisplayMemberBinding="{Binding TaskDuration}" /> 
        <GridViewColumn Header="Task" DisplayMemberBinding="{Binding TaskString}" /> 
       </GridView> 
      </ListView.View> 
     </ListView> 

Я просто хочу, чтобы связать эту ListView (как вы могли бы ожидать от кода выше к объекту:

public class csTaskFileInfo 
{ 
    public DateTime DateOfTasks { get; set; } 
    public ObservableCollection<csTask> obscollTasks { get; set; } 

    public csTaskFileInfo() 
    { 
     obscollTasks = new ObservableCollection<csTask>(); 
    } 
} 

И csTask класс от ObservableCollection:

[Serializable] 
public class csTask:INotifyPropertyChanged 
{ 
    private int _TaskId; 
    private string _TaskString; 
    private DateTime _TaskDate; 
    private TimeSpan _TaskStartTime; 
    private TimeSpan _TaskEndTime; 
    private TimeSpan _TaskDuration; 

    [XmlIgnore] 
    public TimeSpan TaskDuration 
    { 
     get { return _TaskDuration; } 
     set 
     { 
      _TaskDuration = value; 
      Notify("TaskDuration"); 
     } 
    } 
    [XmlIgnore] 
    public TimeSpan TaskEndTime 
    { 
     get { return _TaskEndTime; } 
     set 
     { 
      _TaskEndTime = value; 

      if (TaskEndTime > TaskStartTime) 
      { 
       TaskDuration = TaskEndTime - TaskStartTime; 
      } 

      Notify("TaskEndTime"); 
     } 
    } 
    [XmlIgnore] 
    public TimeSpan TaskStartTime 
    { 
     get { return _TaskStartTime; } 
     set 
     { 
      _TaskStartTime = value; 

      if (_TaskStartTime < _TaskEndTime) 
      { 
       TaskDuration = TaskEndTime - TaskStartTime; 
      } 

      Notify("TaskStartDate"); 
     } 
    } 
    public DateTime TaskDate 
    { 
     get { return _TaskDate; } 
     set 
     { 
      _TaskDate = value; 
      Notify("TaskDate"); 
     } 
    } 

    [XmlElement("TaskDurationString")] 
    public string TaskDurationString { get { return TaskDuration.ToString(); } set { TaskDuration = TimeSpan.Parse(value); } } 
    [XmlElement("TaskEndTimeString")] 
    public string TaskEndTimeString { get { return TaskEndTime.ToString(); } set { TaskEndTime = TimeSpan.Parse(value); } } 
    [XmlElement("TaskStartTimeString")] 
    public string TaskStartTimeString { get { return TaskStartTime.ToString(); } set { TaskStartTime = TimeSpan.Parse(value); } } 


    public string TaskString 
    { 
     get { return _TaskString; } 
     set 
     { 
      _TaskString = value; 
      Notify("TaskString"); 
     } 
    } 
    public int TaskId 
    { 
     get { return _TaskId; } 
     set 
     { 
      _TaskId = value; 
      Notify("TaskId"); 
     } 
    } 

    public csTask(int TaskId, string TaskString,DateTime TaskDate) 
    { 
     this.TaskId = TaskId; 
     this.TaskString = TaskString; 
     this.TaskDate = TaskDate; 
    } 

    public csTask() 
    { 

    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void Notify(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

Как вы можете видеть, INotifyProp ertyChanged уже реализован. Часть, почему я немного смущен:

В более ранней версии, когда я использовал только ObservableCollection, работа была привязана.

Поскольку я использую объект, в котором коллекция существует внутри этого объекта, я не могу заставить его работать.

Не хватает ли чего-нибудь?

Datacontext моего MainWindow, где я использую этот объект, уже настроен на себя.

this.Datacontext = this; 

Некоторые намеки или в виде цифровые значения шкалы ошибки будет очень приятно :)

спасибо!

Привет Daniel

Edit:

Я реализовал INotifyPropertyChanged внутри csTask. (используя его в ObservableCollection внутри csTaskFile)

Кодекс моей MainWindow как вы хотели :):

FileSystemWatcher FileWatcher; 
    public csTaskFileInfo TaskFile { get; set; } 
    public List<FileInfo> obscollFiles { get; set; } 
    private string _FolderPath; 
    public string FolderPath 
    { 
     get { return _FolderPath; } 
     set 
     { 
      _FolderPath = value; 
      Notify("FolderPath"); 
     } 
    } 
    public DirectoryInfo FolderDirectory { get; set; } 

    public MainWindow() 
    { 
     InitializeComponent(); 
     TaskFile = new csTaskFileInfo(); 
     TaskFile.DateOfTasks = DateTime.Now; 
     obscollFiles = new List<FileInfo>(); 
     this.DataContext = this; 
     RegistryKey _RegKey = Registry.CurrentUser.OpenSubKey("Software\\WTT"); 

     if (_RegKey == null) 
     { 
      FolderPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\WTT_Files"; 
     } 
     else 
     { 
      FolderPath = (string)_RegKey.GetValue("FolderDestination") + "\\WTT_Files"; 
     } 

     if (Directory.Exists(FolderPath) == false) 
     { 
      Directory.CreateDirectory(FolderPath); 
     } 

     FolderDirectory = new DirectoryInfo(FolderPath); 

     FileWatcher = new FileSystemWatcher(FolderPath,"*.xml"); 
     FileWatcher.Created += new FileSystemEventHandler (FileWatcher_Changed); 
     FileWatcher.Deleted += new FileSystemEventHandler (FileWatcher_Changed); 
     //FileWatcher.Changed += new FileSystemEventHandler(FileWatcher_Changed); 
     FileWatcher.Renamed += new RenamedEventHandler(FileWatcher_Changed); 
     FileWatcher.EnableRaisingEvents = true; 
     FileWatcher_Changed(null,null); 

     var _temp = from n in obscollFiles 
        where n.Name == (DateTime.Today.ToShortDateString() + ".xml") 
        select n; 
     if (_temp.Count() == 1) 
     { 
      lstFiles.SelectedItem = _temp.Single() as FileInfo; 
     } 
    } 

    private void FileWatcher_Changed(object sender, FileSystemEventArgs e) 
    { 
     obscollFiles = FolderDirectory.GetFiles("*.xml").ToList(); 
     Notify("obscollFiles"); 
    } 

    private void NewTask_Click(object sender, RoutedEventArgs e) 
    { 

     TaskStringWindow _newTaskStringWindow = new TaskStringWindow(); 
     _newTaskStringWindow.Owner = this; 
     _newTaskStringWindow.txtEingabe.Focus(); 
     _newTaskStringWindow.ShowDialog(); 

     if (_newTaskStringWindow.DialogResult == true) 
     { 
      csTask _newTask = new csTask(); 
      if (TaskFile.obscollTasks != null && TaskFile.obscollTasks.Count > 0) 
      { 
       csTask _previousTask; 
       _previousTask = TaskFile.obscollTasks.Last(); 

       _previousTask.TaskEndTime = TimeSpan.Parse(DateTime.Now.ToLongTimeString()); 

       _newTask.TaskId = _previousTask.TaskId + 1; 
       _newTask.TaskDate = TaskFile.DateOfTasks; 
       _newTask.TaskStartTime = TimeSpan.Parse(DateTime.Now.ToLongTimeString()); 
      } 
      else 
      { 
       _newTask.TaskId = 1; 
       _newTask.TaskDate = DateTime.Now; 
       _newTask.TaskStartTime = TimeSpan.Parse(DateTime.Now.ToLongTimeString()); 
      } 
      _newTask.TaskString = _newTaskStringWindow.txtEingabe.Text; 
      TaskFile.obscollTasks.Add(_newTask); 
      //lstTasks.DataContext = TaskFile.obscollTasks; 
     } 
    } 

    private void SaveCurrentFile_Click(object sender, RoutedEventArgs e) 
    { 
     XmlSerializer XmlSer = new XmlSerializer(typeof(csTaskFileInfo)); 

     if (Directory.Exists(FolderPath) == false) 
     { 
      Directory.CreateDirectory(FolderPath); 
     } 
     FileStream stream = new FileStream(FolderPath + @"\" + DateTime.Now.ToShortDateString() + ".xml", FileMode.Create); 
     XmlSer.Serialize(stream, TaskFile); 
     stream.Close(); 

    } 

    private void ResetSearchByDate_Click(object sender, RoutedEventArgs e) 
    { 
     //lstTasks.DataContext = TaskFile.obscollTasks; 
    } 

    private void LoadFile_Click(object sender, RoutedEventArgs e) 
    { 
     OpenFileDialog OpenFile = new OpenFileDialog(); 
     OpenFile.Filter = ("XAML-Dateien |*.xml"); 
     if (OpenFile.ShowDialog(this) == true) 
     { 
      TaskFile.obscollTasks.Clear(); 
      FileInfo _tempFileInfo = new FileInfo(OpenFile.FileName); 
      obscollFiles.Add(_tempFileInfo); 
      lstFiles.SelectedItem = _tempFileInfo; 
     } 
    } 

    private void LoadFile(FileInfo File) 
    { 
     try 
     { 
     //XmlSerializer XmlSer = new XmlSerializer(typeof(csTaskFileInfo)); 
     //FileStream stream = new FileStream(File.FullName, FileMode.Open); 
     //TaskFile = (csTaskFileInfo)XmlSer.Deserialize(stream); 
      using (FileStream fStream = new FileStream(File.FullName,FileMode.Open)) 
      { 
       XmlSerializer XmlSer = new XmlSerializer(typeof(csTaskFileInfo)); 

       using (StreamReader sReader = new StreamReader(fStream,Encoding.UTF8)) 
       { 
        TaskFile = (csTaskFileInfo)XmlSer.Deserialize(sReader); 
        //lstTasks.DataContext = TaskFile.obscollTasks; 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.InnerException.ToString(),"Fehler", MessageBoxButton.OK, MessageBoxImage.Error); 
     } 
    } 

    private void SetFolder_Click(object sender, RoutedEventArgs e) 
    { 
     System.Windows.Forms.FolderBrowserDialog _SelectFolder = new System.Windows.Forms.FolderBrowserDialog(); 

     System.Windows.Forms.DialogResult _result = _SelectFolder.ShowDialog(); 

     if (_result == System.Windows.Forms.DialogResult.OK) 
     { 
      RegistryKey _RegKey = Registry.CurrentUser.OpenSubKey("Software",true); 
      _RegKey.CreateSubKey("WTT"); 
      _RegKey = _RegKey.OpenSubKey("WTT",true); 
      _RegKey.SetValue("FolderDestination", _SelectFolder.SelectedPath); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected void Notify(string propertyName) 
    { 
     if (this.PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    private void lstFiles_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) 
    { 
     TaskFile.obscollTasks.Clear(); 
     LoadFile(lstFiles.SelectedItem as FileInfo); 
    } 

    private void HandleDoubleClick(object sender,MouseButtonEventArgs e) 
    { 
     TaskChangeData TaskChange = new TaskChangeData(TaskFile.obscollTasks, lstTasks.SelectedItem as csTask); 

     TaskChange.ShowDialog(); 
    } 
+0

Вы реализовали INotifyPropertyChanged? Проверьте ссылку о том, кто вы это делаете. http://msdn.microsoft.com/en-us/library/ms743695.aspx –

+0

Можете ли вы показать код вашего окна? –

+0

Посмотрите на окно вывода и сообщите нам ошибки привязки данных, которые вы видите. – Dennis

ответ

0

Поскольку нет в TaskFile нет obscollFiles (есть obscollTasks вместо этого) не должна быть

<ListView Name="lstTasks" SelectionMode="Single" 
ItemContainerStyle="{StaticResource itemstyle}" 
ItemsSource="{Binding Path=TaskFile.obscollTasks}" > 
.... 

?

+0

Ах, да, это правда: D Спасибо! Но эта ошибка остается прежней. – Daniel

+0

@ Даниэль см. Мой обновленный ответ и попробуйте еще раз :) –

+1

Хорошо, спасибо. Реализовала его с новым путем. Ошибка связи, указанная в выводе. Данные по-прежнему не отображаются в MainWindow, но я думаю, что это может быть проблемой, когда мне нужно следить за позициями, где происходит PropertyChanged.Спасибо, Андрей! – Daniel

Смежные вопросы