none
Update ViewModel's data without recompiling the application?

    Question

  • xaml.cs ------------------------------------------------

    public partial class Window1 : Window
    {
    public Window1()      
    {
    InitializeComponent();
    DataContext = new ComboBoxPatterns();
    }

    ComboBoxPatterns.cs ----------------------------------

    public class ComboBoxPatterns
     {
    public List<string> Collection1 { get; set; }

    public List<string> Collection2 { get; set; } 
    public ComboBoxPatterns()
    {
    Collection1 = new List<string>()
     {
         "Whatever",
         "Whatever",
     };

    Collection2 = new List<string>() {
         "Whatever2",
         "Whatever2",
     };

    xaml --------------------------------------------

    <ComboBox
    ItemsSource="{Binding Collection1}"/>
    <TextBox
    Text="{Binding Collection2}" />

    I often have to add new entries to Collection1 and Collection2. 

    So far, I've just added the new entries manually and recompile the application to make the new entries available.

    My question is, is there a way to make changes and make them available without recompiling the application?

    Wednesday, June 12, 2019 11:56 AM

Answers

  • The example below is working fine using an editable ComboBox.

    xaml ............................

    <ComboBox
                VerticalContentAlignment="Center"
                HorizontalContentAlignment="Left"
                TextSearch.TextPath=""
                Width="800"
                Height="24"
                IsSynchronizedWithCurrentItem="True"
                IsEditable="True"
                x:Name="ComboBox1"
                Loaded="ComboBox1_Loaded"
                FontFamily="Arial"
                FontSize="14" />

    xaml.cs ....................................................

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.IO;

    namespace A15
    {
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
            }
            void ComboBox1_Loaded(object sender, RoutedEventArgs e)
            {
              List<string> lines = new List<string>();
              using (StreamReader reader = new StreamReader("d:/1.txt"))
            {
             while(!reader.EndOfStream)
            {
             ComboBox1.Items.Add(reader.ReadLine());
            }
            }
            }
        }
    }

    1.txt contains a list of simple strings (one item per line)

    • Marked as answer by John-33 Sunday, June 16, 2019 4:26 AM
    Friday, June 14, 2019 12:39 PM

All replies

  • See this.
    Wednesday, June 12, 2019 2:47 PM
  • See this.

    Thanks but I don't think it's worth the hassle to be quite honest.

    I'd welcome simple approaches if there're any :)

    Wednesday, June 12, 2019 3:29 PM
  • Since you are storing your collection in the app you will have to compile the app each time the collection changes.  Not really a good way to do it.

    To do it without having to compile you need to store the collection in an external (to the app) data store.  This can be as simple as a text file or as sophisticated as a database file.

    If your real entries are just strings I would suggest a file with one item per line.  It is simple to read into a list.


    Lloyd Sheen

    Wednesday, June 12, 2019 6:31 PM
  •  you need to store the collection in an external (to the app) data store.  This can be as simple as a text file

    If your real entries are just strings I would suggest a file with one item per line.  It is simple to read into a list.



    Yes, my original idea was to use a simple textfile but ...

    I want to bind the AutoCompleteTextBox (WPFToolkit) to a textfile.

    1.xaml ---------------

    <toolkit:AutoCompleteBox x:Name="SearchBox" Width="885" Height="25"
    HorizontalAlignment="Right"
    VerticalAlignment="Top"                
    ItemsSource="{Binding Terms}"
    SelectedItem="{Binding SelectedNames, Mode=TwoWay}" Margin="0,205,0,0" />

    ViewModel.cs ----------------------------

    using System;
    using System.Text;
    using System.Linq;
    using System.Collections.Generic;
    using System.IO;

    namespace App
    {
     public class ViewModel
    {
    public string Terms { get; set; }
    public void ReadFile(string path)       
    {
    Terms = File.ReadAllText("d:/1.txt");

    }
    }

    No errors there but AutoCompleteTextBox doesn't load any data stored in 1.txt.

    What am I doing wrong?

    Thursday, June 13, 2019 5:05 AM
  • Hi    John-33,

    >>No errors there but AutoCompleteTextBox doesn't load any data stored in 1.txt.

    What am I doing wrong?

    I think your code should be incomplete.

    So, I want to know, where you will call the ReadFile() method and get the value?

    Next, when you get the value and want to update the UI, you need to implement the INotifyPropertyChanged interface and  use the TwoWay Mode. INotifyPropertyChanged interface is used to notify the view or ViewModel that it does not matter which property is binding; it is updated.

    For your reference:
    Explain INotifyPropertyChanged In WPF - MVVM


    If necessary,  you can upload your demo to OneDrive(Including your test material). We can download it and debugging. This will help us quickly analyze your problem.

    Best regards

    Yong Lu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, June 13, 2019 6:34 AM
    Moderator
  • I really appreciate the help but I'm lost as this is more complicated that I thought.

    Window1.xaml ..............................

    <Window x:Class="Demo.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:toolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit"
    Title="Demo" Height="300" Width="300">
    <Grid>
    <toolkit:AutoCompleteBox x:Name="SearchBox" Width="105" Height="25"
    HorizontalAlignment="Center"
    VerticalAlignment="Top"                
    ItemsSource="{Binding Names}"
    SelectedItem="{Binding SelectedNames, Mode=TwoWay}" Margin="0,100,0,0" />      
    </Grid>
    </Window>

    ViewModel.cs ...........................................

    using System;
    using System.Text;
    using System.Linq;
    using System.Collections.Generic; 

    namespace Demo
    {
    public class ViewModel
    {
    public List<string> Names { get; set; }
    public ViewModel()
    {
    Names = new List<string>()
    { "Blue"
    "Black"
    "Brown",
    };
    }
    }
    }

    Window1.xaml.cs ..............................................

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;

    namespace Demo
    {
    public partial class Window1 : Window
    {
     public Window1()
    {
    InitializeComponent();
    DataContext = new ViewModel();
    }
    }
    }

    This is working perfectly with the ViewModel. I just thought a separate textfile with strings (i.e. Black, Blue ....) would be more convenient and I don't have to recompile the application every time I add a new entry.

    A more simple and basic example would be great guys.


    Thursday, June 13, 2019 10:32 AM
  • The example below is working fine using an editable ComboBox.

    xaml ............................

    <ComboBox
                VerticalContentAlignment="Center"
                HorizontalContentAlignment="Left"
                TextSearch.TextPath=""
                Width="800"
                Height="24"
                IsSynchronizedWithCurrentItem="True"
                IsEditable="True"
                x:Name="ComboBox1"
                Loaded="ComboBox1_Loaded"
                FontFamily="Arial"
                FontSize="14" />

    xaml.cs ....................................................

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.IO;

    namespace A15
    {
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
            }
            void ComboBox1_Loaded(object sender, RoutedEventArgs e)
            {
              List<string> lines = new List<string>();
              using (StreamReader reader = new StreamReader("d:/1.txt"))
            {
             while(!reader.EndOfStream)
            {
             ComboBox1.Items.Add(reader.ReadLine());
            }
            }
            }
        }
    }

    1.txt contains a list of simple strings (one item per line)

    • Marked as answer by John-33 Sunday, June 16, 2019 4:26 AM
    Friday, June 14, 2019 12:39 PM