0

So I have a DataGrid which is bound to a ICollectionView. Now, I have one column which I want it to be bound not to the ICollectionView, but to a local variable from inside of the class.

How do I make that in the code?

<DataGrid
                    x:Name="DG_StudentsList"
                    FontSize="20"
                    HorizontalContentAlignment="Center"
                    VerticalContentAlignment="Center"
                    AutoGenerateColumns="False">
                    <DataGrid.Columns>
                        <DataGridTextColumn Binding="{Binding Id}" Header="מ''ס"/>
                        <DataGridTextColumn Binding="{Binding Name}" Header="שם"/>
                        <DataGridTextColumn Binding="{Binding PhoneNum}" Header="טלפון"/>
                        <DataGridTemplateColumn Header="ספרים מושאלים">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <ComboBox ItemsSource="{Binding Path=BorrowedBooks}" DisplayMemberPath="BookName" SelectionChanged="CB_BookName_SelectionChanged"/>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                    </DataGrid.Columns>
                </DataGrid>

Just to be clear, I want to add a new DataGridTextColumn which is the one that will be bound to the local variable.

public partial class StudentsList : Window
    {
        ObservableCollection<Student> OBStudents = new ObservableCollection<Student>();
        CollectionViewSource StudentsCollection;
        Predicate<object> yourCostumFilter;
        ICollectionView Itemlist;
        Student s = Student.Instance;
        //string ss = "wel welwel";
        public StudentsList()
        {
            InitializeComponent();
            InitializeObservableCollection();
        }

        private void InitializeObservableCollection()
        {
            foreach (var item in s.GetStudentList())
                OBStudents.Add(item);
            StudentsCollection = new CollectionViewSource { Source = OBStudents };
            Itemlist = StudentsCollection.View;
            DG_StudentsList.ItemsSource = Itemlist;
        }
        private void BTN_Exit_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
        private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
        {

        }
        private void Window_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ChangedButton == MouseButton.Left)
                this.DragMove();
        }
        private void CB_Filter_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (!string.IsNullOrEmpty(sender.ToString()))
                TB_SearchBox.IsEnabled = true;
            else
                TB_SearchBox.IsEnabled = false;
        }

        private void TB_SearchBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (CB_Filter.SelectedIndex == 0)
                yourCostumFilter = new Predicate<object>(item => ((Student)item).Name.Contains(TB_SearchBox.Text));
            else if (CB_Filter.SelectedIndex == 1)
                yourCostumFilter = new Predicate<object>(item => ((Student)item).PhoneNum.Contains(TB_SearchBox.Text));
            Itemlist.Filter = yourCostumFilter;
            Itemlist.Refresh();
        }
        private void CB_BookName_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox CB = (ComboBox)sender;
            BookBorrowed borrowedBookDate,bbHolder =(BookBorrowed) CB.SelectedItem;
            borrowedBookDate = s.GetBorrowedBookInfo((Student)DG_StudentsList.SelectedItem, bbHolder.BookName);
            //ss = borrowedBookDate.BookLendDate.ToShortDateString();
            /*DataGridTextColumn tc = new DataGridTextColumn();
            tc.Header = "תאריך השאלה";
            tc.Binding = new Binding("borrowedBookDate.BookLendDate, TargetNullValue=borrowedBookDate.BookLendDate");
            DG_StudentsList.Columns.Add(tc);*/
        }

    }
    public class Student
    {
        private readonly TextFileHandler TFH = TextFileHandler.Instance;
        public List<string> Lines { get; private set; } = new List<string>();
        private static readonly Lazy<Student> student = new Lazy<Student>(() => new Student());
        public static Student Instance { get { return student.Value; } }
        private Book b = Book.Instance;

        private StudentsWindow SW;

        public int Id { get; set; }
        public string Name { get; set; }
        public string PhoneNum { get; set; }
        public List<BookBorrowed> BorrowedBooks { get; set; }

        private Student() { }
        private Student(int id, string name, string phoneNum, List<BookBorrowed> borrowedBooks)
        {
            Id = id;
            Name = name;
            PhoneNum = phoneNum;
            BorrowedBooks = borrowedBooks;
        }
        public Student(string Name, string PhoneNum)
        {
            Id = GenerateID();
            this.Name = Name;
            this.PhoneNum = PhoneNum;
            BorrowedBooks = new List<BookBorrowed>();
        }
        public Student(string Name, string PhoneNum, List<BookBorrowed> BorrowedBooks)
        {
            Id = GenerateID();
            this.Name = Name;
            this.PhoneNum = PhoneNum;
            this.BorrowedBooks = BorrowedBooks;
        }

        public void AddStudent(Student newStudent)
        {
            SW = Application.Current.Windows.OfType<StudentsWindow>().First();
            UpdateStudentsLinesList();
            if (!TFH.CheckLineExistens($"שם:{newStudent.Name}", Paths.studentsFile) ||
                !TFH.CheckLineExistens($"טלפון:{newStudent.PhoneNum}", Paths.studentsFile))
            {
                Lines.Add($"מ''ס:{GenerateID()}\n[");
                Lines.Add($"שם:{newStudent.Name}");
                Lines.Add($"טלפון:{newStudent.PhoneNum}");
                Lines.Add($"ספרים מושאלים");
                Lines.Add(@"{");
                foreach (var book in newStudent.BorrowedBooks)
                {
                    Lines.Add($"שם הספר:{book.BookName}");
                    Lines.Add($"תאריך השאלה:{DateTime.Now.ToShortDateString()}");
                }
                Lines.Add(@"}");
                Lines.Add("]");
                SW.WriteToConsole($"התלמיד {newStudent.Name} נוסף בהצלחה ");
            }
            else
            {
                SW.WriteToConsole($"התלמיד {newStudent.Name} כבר קיים במערכת ");
            }
            TFH.OverWriteFile(Lines, Paths.studentsFile);
        }
        public void AddStudentWithoutOuput(Student newStudent)
        {
            SW = Application.Current.Windows.OfType<StudentsWindow>().First();
            UpdateStudentsLinesList();
            if (!TFH.CheckLineExistens($"שם:{newStudent.Name}", Paths.studentsFile) ||
                !TFH.CheckLineExistens($"טלפון:{newStudent.PhoneNum}", Paths.studentsFile))
            {
                Lines.Add($"מ''ס:{GenerateID()}\n[");
                Lines.Add($"שם:{newStudent.Name}");
                Lines.Add($"טלפון:{newStudent.PhoneNum}");
                Lines.Add($"ספרים מושאלים");
                Lines.Add(@"{");
                foreach (var book in newStudent.BorrowedBooks)
                {
                    Lines.Add($"שם הספר:{book.BookName}");
                    Lines.Add($"תאריך השאלה:{DateTime.Now.ToShortDateString()}");
                }
                Lines.Add(@"}");
                Lines.Add("]");
            }
            TFH.OverWriteFile(Lines, Paths.studentsFile);
        }
        public void AddBookToStudent(Book newBook, Student student)
        {
            SW = Application.Current.Windows.OfType<StudentsWindow>().First();
            bool bookExist = false;
            student.BorrowedBooks.ForEach(bookName => {
                if (bookName.Equals(newBook.BookName))
                    bookExist = true;
            });
            if (
                !bookExist &
                newBook.Quantity != 0)
            {
                student.BorrowedBooks.Add(new BookBorrowed(newBook.BookName));
                StudentWithUpdatedBooks(student);
                Book bookWithLowerQuantity = new Book(newBook);
                bookWithLowerQuantity.Quantity--;
                b.UpdateInfo(newBook, bookWithLowerQuantity);
                SW.WriteToConsole($"הספר {newBook.BookName} נוסף בהצלחה לתלמיד {student.Name}");
                SW.WriteToConsole($"כמות הספרים הנותרים מהספר {newBook.BookName}: {bookWithLowerQuantity.Quantity}");
            }
            else
            {
                if(bookExist)
                    SW.WriteToConsole($"הספר {newBook.BookName} כבר קיים אצל התלמיד {student.Name}");
                else if(newBook.Quantity == 0)
                    SW.WriteToConsole($"אין עוד מספר זה בסיפרייה. כמות הספרים מהספר {newBook.BookName}: {newBook.Quantity--}");
            }
        }

        public void DeleteStudent(Student student)
        {
            UpdateStudentsLinesList();
            if (TFH.CheckLineExistens($"שם:{student.Name}", Paths.studentsFile) &
                TFH.CheckLineExistens($"טלפון:{student.PhoneNum}", Paths.studentsFile))
            {
                if (student.BorrowedBooks.Count != 0)
                {
                    List<Book> booksStudentHave = new List<Book>(), booksToReturn = new List<Book>();
                    student.BorrowedBooks.ForEach(bookName => {
                        booksStudentHave.Add(b.GetBookByInfo($"שם:{bookName}"));
                    });
                    booksStudentHave.ForEach(book => {
                        Book bHolder = new Book(book);
                        bHolder.Quantity += book.Quantity;
                        b.UpdateInfo(book,bHolder);
                    });
                }
                bool inMidName = false, inMidPhone = false, insindMide = false;
                List<string> newList = new List<string>();
                int idLine = new int(), currentline = 1;
                foreach (var line in Lines)
                {
                    if (line.Equals($"שם:{student.Name}"))
                        inMidName = true;
                    if (line.Equals($"טלפון:{student.PhoneNum}"))
                        inMidPhone = true;
                    if (inMidName & inMidPhone)
                    {
                        idLine = currentline - 4;
                        break;
                    }
                    currentline++;
                }
                int id = int.Parse(Lines[idLine].Substring(Lines[idLine].IndexOf(":")+1));
                foreach (var line in Lines)
                {
                    if (line.Equals($"מ''ס:{id}"))
                        insindMide = true;
                    if (insindMide)
                    {
                        if (line.Equals("]"))
                            insindMide = false;
                    }
                    else
                        newList.Add(line);
                }
                TFH.OverWriteFile(newList, Paths.studentsFile);
            }
        }
        public void DeleteStudent(string name, string phoneNum)
        {
            UpdateStudentsLinesList();
            if (TFH.CheckLineExistens($"שם:{name}", Paths.studentsFile) &
                TFH.CheckLineExistens($"טלפון:{phoneNum}", Paths.studentsFile))
            {
                bool inMidName = false, inMidPhone = false, insindMide = false;
                List<string> newList = new List<string>();
                int idLine = new int(), currentline = 1;
                foreach (var line in Lines)
                {
                    if (line.Equals($"שם:{name}"))
                        inMidName = true;
                    if (line.Equals($"טלפון:{phoneNum}"))
                        inMidPhone = true;
                    if (inMidName & inMidPhone)
                    {
                        idLine = currentline - 4;
                        break;
                    }
                    currentline++;
                }
                int id = int.Parse(Lines[idLine].Substring(Lines[idLine].IndexOf(":") + 1));
                foreach (var line in Lines)
                {
                    if (line.Equals($"מ''ס:{id}"))
                        insindMide = true;
                    if (insindMide)
                    {
                        if (line.Equals("]"))
                            insindMide = false;
                    }
                    else
                        newList.Add(line);
                }
                TFH.OverWriteFile(newList, Paths.studentsFile);
            }
        }

        public void StudentWithUpdatedBooks(Student student)
        {
            bool inMid = false;
            List<string> updatedList = new List<string>();
            foreach (var line in TFH.GetAllRawLines(Paths.studentsFile))
            {
                if (line.Equals($"מ''ס:{student.Id}"))
                    inMid = true;
                if (inMid)
                {
                    if (line.Equals("]"))
                        inMid = false;
                }
                else
                    updatedList.Add(line);
            }
            TFH.OverWriteFile(updatedList, Paths.studentsFile);
            AddStudentWithoutOuput(student);
        }

        public void UpdateInfo(Student student,Student updatedStudent)
        {
            bool inMid = false;
            List<string> updatedList = new List<string>();
            foreach (var line in TFH.GetAllRawLines(Paths.studentsFile))
            {
                if (line.Equals($"מ''ס:{student.Id}"))
                    inMid = true;
                if (inMid)
                {
                    if (line.Equals("]"))
                        inMid = false;
                }
                else
                    updatedList.Add(line);
            }
            TFH.OverWriteFile(updatedList,Paths.studentsFile);
            AddStudentWithoutOuput(updatedStudent);
        }

        private int GenerateID()
        {
            int newID = 0;
            foreach (string line in TFH.GetAllRawLines(Paths.studentsFile))
            {
                if (line.Contains("מ''ס:"))
                    newID++;
            }
            return newID;
        }

        public List<string> GetNewStudent(Student student)
        {
            UpdateStudentsLinesList();
            List<string> newLines = new List<string>();
            if (!TFH.CheckLineExistens($"שם:{student.Name}", Paths.studentsFile) &
                !TFH.CheckLineExistens($"טלפון:{student.PhoneNum}", Paths.studentsFile))
            {
                Lines.Add($"מ''ס:{student.Id}\n[");
                Lines.Add($"שם:{student.Name}");
                Lines.Add($"טלפון:{student.PhoneNum}");
                Lines.Add($"ספרים מושאלים");
                Lines.Add(@"{");
                foreach (var book in student.BorrowedBooks)
                {
                    Lines.Add($"שם הספר:{book.BookName}");
                    Lines.Add($"תאריך השאלה:{DateTime.Now.ToShortDateString()}");
                }
                Lines.Add(@"}");
                Lines.Add("]");
            }
            return newLines;
        }
        public List<Student> GetStudentList()
        {
            List<Student> newList = new List<Student>();
            foreach (var line in TFH.GetAllRawLines(Paths.studentsFile))
            {
                if (line.Contains("מ''ס"))
                    newList.Add(GetStudentByInfo(line));
            }
            return newList;
        }
        public Student GetStudentByInfo(string info)
        {
            string name = null, phoneNum = null,BB_name = null;
            int id = new int();
            DateTime BB_lent;
            List<BookBorrowed> borrowedBooks = new List<BookBorrowed>();
            bool inMid = false, inMidBooks = false, insideBook = false;
            if (info.Contains("מ''ס"))
            {
                foreach (var line in TFH.GetAllRawLines(Paths.studentsFile))
                {
                    if (line.Equals(info))
                    {
                        inMid = true;
                        id = int.Parse(line.Substring(line.IndexOf(":") + 1));
                    }
                    if (inMid)
                    {
                        if (line.Equals("]"))
                            break;
                        else if (line.Contains("שם:"))
                            name = line.Substring(line.IndexOf(":") + 1);
                        else if (line.Contains("טלפון:"))
                            phoneNum = line.Substring(line.IndexOf(":") + 1);
                        else if (line.Equals("{"))
                        {
                            inMidBooks = true;
                            continue;
                        }
                        else if (line.Equals("}"))
                            inMidBooks = false;
                        if (inMidBooks)
                        {
                            if (line.Contains("שם הספר:"))
                            {
                                BB_name = line.Substring(line.IndexOf(":") + 1);
                                insideBook = true;
                                continue;
                            }
                            if (insideBook)
                            {
                                BB_lent = DateTime.Parse(line.Substring(line.IndexOf(":")+1));
                                borrowedBooks.Add(new BookBorrowed(BB_name,BB_lent));
                                insideBook = false;
                            }

                        }
                    }
                }
                return new Student(id, name, phoneNum, borrowedBooks);
            }
            return null;
        }

        public void UpdateStudentsLinesList() { Lines = TFH.GetAllRawLines(Paths.studentsFile); }

        public BookBorrowed GetBorrowedBookInfo(Student student,string borrowedBookName)
        {
            Student currentStudent = GetStudentByInfo($"מ''ס:{student.Id}");
            foreach (var book in currentStudent.BorrowedBooks)
            {
                if (book.BookName.Equals(borrowedBookName))
                    return new BookBorrowed(book.BookName, book.BookLendDate);
            }
            return null;
        }
    }
public class BookBorrowed
    {
        public string BookName { get; set; }
        public DateTime BookLendDate { get; set; }
        public BookBorrowed(string BookName)
        {
            this.BookName = BookName;
            this.BookLendDate = DateTime.Now;
        }

        public BookBorrowed(string BookName, DateTime BookLendDate)
        {
            this.BookName = BookName;
            this.BookLendDate = BookLendDate;
        }
    }
  • To know if I understood you, [this question](https://stackoverflow.com/q/3920040/1271037) is this question similar to yours? And if so, the solution is also good for you? – dovid Aug 06 '20 at 10:42
  • @dovid well it feels very close but it didn't work. lets say I have an object named `borrowedBookDate` which is a string that is changing. every time you change the book in the `ComboBox`, the `borrowedBookDate` value will change as well. Now how do i get access to doing that while still binding my `DataGrid` to a `ICollectionView`? – Yuval Peretz Aug 06 '20 at 11:08
  • the `borrowedBookDate ` is per row (of the ICollectionView list), or globaly for all list? – dovid Aug 06 '20 at 11:13
  • @dovid if you mean that it is represented in each row for each item in the `DataGrid`, then yes it is per row. the object `borrowedBookDate` iit self is global in the C# code behind this window. – Yuval Peretz Aug 06 '20 at 11:21
  • Sorry I did not understand. You can add to the question the class of the row, and the class pertaining to the combo list + explain the relation between them? – dovid Aug 06 '20 at 15:32
  • @dovid Adding right now – Yuval Peretz Aug 06 '20 at 15:51
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/219351/discussion-between-yuval-peretz-and-dovid). – Yuval Peretz Aug 06 '20 at 16:22

1 Answers1

0

No, you can't bind to a local variable. First of all, there is a local scope, a instance scope and a class scope. A local variable only lives in a local scope e.g. the block of an if-statement or a method body. As soon the instruction pointer leaves this scope the variable does no longer exist. You may mean an instance variable i.e. field, which lives as long as the object instance is living. Class variables would be static fields, variables that don't belong to the class instance, but the class itself.

Anyway, you can only bind to public properties. Microsoft Docs: Binding Source Types
If you have a public property, then you can also bind a column to it.

A common CLR property would also work. But in controls it is recommended to implement properties that serve as a binding source as DependencyProperty.

Dependency properties overview, Data binding overview in WPF

MainWindow.xaml.cs

partial class MainWindow : Window
{
  public static readonly DependencyProperty BorrowedBookDateProperty = DependencyProperty.Register(
    "BorrowedBookDate",
    typeof(DateTime),
    typeof(MainWindow),
    new PropertyMetadata(default(DateTime)));

  public DateTime TextValue
  {
    get => (DateTime) GetValue(MainWindow.BorrowedBookDateProperty);
    set => SetValue(MainWindow.BorrowedBookDateProperty, value);
  }

  public MainWindow()
  {
    this.BorrowedBook = DateTime.Now;
  }
}

MainWindow.xaml

<Window>
  <DataGrid>
    <DataGrid.Columns>
      <DataGridTextColumn Header="Borrowed Book Date" 
                          Binding="{Binding RelativeSource={RelativeSource AncestorType=main:MainWindow}, Path=BorrowedBookDate}" />
    </DataGrid.Columns>
  </DataGrid>
</Window>
BionicCode
  • 13,277
  • 2
  • 17
  • 33