Search code examples
c#wpfwpfdatagrid

Binding a 2 dimensional bool array to datagrid in wpf


I have to create a Matrix like datagrid of type bool using 2D Array. I have a set of boolean string that is needed to be evaluated for each cell in the datagrid as follows

for e.g

cell[0,0] = ((server1 || server 2) && server 3)

cell[0,1] = ((server1 && server 3) && server 4)

cell[1,0] = ((server3 && server 2) || server 4)

the values for server N is Running or Stopped and it is got from the database.

how to create a 2D matrix datagrid and how to evaluate the boolean string so that the final result is TRUE or FALSE for each datagrid cell.

I had a look at this link 2D array for string and took this as an example, but I dont know where should I call these evaluation strings. Do I have to store them in an XML file and then call them or is there anyother way to call them..

What I have tried :

public MatrixPage()
{
InitializeComponent();
bool[,] matrixcell = new bool[10, 22];

matrixcell[0, 0] = // should I place the Evaluation string here;
matrixcell[0, 1] = ;
for  (int i = 0; i < 10; i++)
{
for (int j = 0; j < 22; j++)
{
 matrixcell[i, j] = // or Should I call here the evaluation boolean string for each    iteration respective to the row/column from a file like XML or a any other file ??
}
}
 var datsource = (from i in Enumerable.Range(0, matrixcell.GetLength(0))
    select new clsdatasource(matrixcell[i, 0], matrixcell[i, 1], matrixcell[i,3])).ToList();
 this.dg1.ItemsSource = datsource;
}
public class clsdatasource
{
public bool str1 { get; set; }
public bool str2 { get; set; }
public bool str3 { get; set; }
public clsdatasource(bool s1, bool s2,bool s3)
{
 this.str1 = s1;
 this.str2 = s2;
 this.str3 = s3;
}
}

XAML

  <Grid>
        <DataGrid x:Name="dg1" CanUserAddRows="False" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="System1" Binding="{Binding str1}"/>
                <DataGridTextColumn Header="System2" Binding="{Binding str2}"/>
                <DataGridTextColumn Header="System3" Binding="{Binding str3}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>

Kindly help.. if the question is not clear to understand, please comment, I will try to explain more clearly


Solution

  • Your class would like like this...

    public class Clsdatasource
    {
        public bool Str1 { get; set; }
        public bool Str2 { get; set; }
        public bool Str3 { get; set; }
        public Clsdatasource(){}
        public Clsdatasource(bool s1, bool s2, bool s3)
        {
            Str1 = s1;
            Str2 = s2;
            Str3 = s3;
        }
    }
    

    And your collection of those would look like this...

    public class ClsdataSourceCollection : ObservableCollection<Clsdatasource>
    {
        private const string FileName = "MyData.xml";
        private readonly XmlSerializer _serializer = new XmlSerializer(typeof(List<Clsdatasource>));
        public void LoadData(Action onCompleted)
        {
            using (StreamReader sr = new StreamReader(FileName))
            {
                var s = _serializer.Deserialize(sr) as List<Clsdatasource>;
                if (s != null)
                {
                    Clear();
                    s.ForEach(Add);
                }
            }
            onCompleted();
        }
        public void SaveData(Action onCompleted)
        {
            using (StreamWriter sw = new StreamWriter(FileName))
            {
                List<Clsdatasource> tosave = new List<Clsdatasource>();
                tosave.AddRange(this);
                _serializer.Serialize(sw, tosave);
            }
            onCompleted();
        }
    }
    

    And you could see what's going on with this snippet...

    private static void TestSaving()
    {
        ClsdataSourceCollection collection = new ClsdataSourceCollection();
        for (int i = 0; i < 100; i++)
        {
            collection.Add(new Clsdatasource(true, true, true));
        }
        collection.SaveData(()=> Console.WriteLine("Saved"));
    }
    private static void TestLoading()
    {
        ClsdataSourceCollection collection = new ClsdataSourceCollection();
        collection.LoadData(() => Console.WriteLine("Loaded"));
    }
    

    Those two methods just do a create, save, and load. The artefact is an XML file in the root app directory called MyData.xml. You need to code in all the corner cases and error detection and races.

    The last step in the whole shebang is to set this.dg1.ItemsSource = collection;

    Remember that if you want real-time updates to your grid, the Clsdatasource class has to inherit from INotifyPropertyChanged, which is a different question altogether.

    That should get you started with serialization. It comes 'out of the box' since about .NET 3 or so....