1
votes

I have created a very simple database application as I am very new to WPF. Eventually I was able to to use navigation buttons in winform (without using databindings). I have reached a problem which I hope is a very simple one but I then again I don't know?

Problem

When I use navigation buttons data is not showing in combox but it seems there are no problems with textboxes, it basically showing empty. I have a listview so entire record is showing when CUD operation is. Have I missed out something?

Partial class and showdata method I have created

 public partial class MainWindow : Window
 {
     SqlConnection mconn;
     int MaxRows = 0;
     int rno;
     DataSet ds;

     private void MaxRow()
     {
         MaxRows = ds.Tables[0].Rows.Count;
     }
}

public void ShowData()
    {
        try
        {
            //pardon me this looks rather tacty

            SqlCommand comm = new SqlCommand("Select * from tblTableB", mconn);
            DataTable dt = new DataTable();
            SqlDataAdapter da = new SqlDataAdapter(comm);
            da.Fill(dt);
            listView1.DataContext = dt.DefaultView;

            da = new SqlDataAdapter("select * from tblTableB", mconn);
            ds = new DataSet();
            da.Fill(ds, "TestDatabaseB");
            da.Update(ds, "TestDatabaseB");
            this.MaxRow();

            txtID.Text = ds.Tables[0].Rows[rno][0].ToString();
            txtName.Text = ds.Tables[0].Rows[rno][1].ToString();
            cBHealthDetails.Text = ds.Tables[0].Rows[rno][2].ToString(); //data not showing 
            when  navigation buttons are used. CB is showning empty

        }
        catch (Exception ex)
        {
            MessageBox.Show("Error: " + ex.Message);
        }
    }

Navigation method examples

private void PreRec_Click(object sender, RoutedEventArgs e)
    {
        if (ds.Tables[0].Rows.Count > 0)
        {
            if (rno > 0)
            {
                rno--;
                ShowData();
            }
        }
    }

    private void NxtRec_Click(object sender, RoutedEventArgs e)
    {
        if (ds.Tables[0].Rows.Count > 0)
        {
            if (rno < ds.Tables[0].Rows.Count - 1)
            {
                rno++;
                ShowData();
            }
        }
    }

XAML Code

<Window x:Class="WpfApplication4.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="381" Width="406" Loaded="Window_Loaded">
<Grid>
    <Grid Height="342" HorizontalAlignment="Left"  Name="grid1" VerticalAlignment="Top" Width="384">
        <ListView Height="134" HorizontalAlignment="Left" Name="listView1"  ItemsSource="{Binding}" VerticalAlignment="Top" Width="384">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="ID" DisplayMemberBinding="{Binding Path=ID}"></GridViewColumn>
                    <GridViewColumn Header="Name"  DisplayMemberBinding="{Binding Path=Name}"></GridViewColumn>
                    <GridViewColumn Header="Health Details" DisplayMemberBinding="{Binding Path=HealthDetails}"></GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>
        <Label Content="Name" Height="28" HorizontalAlignment="Left" Margin="7,181,0,0" Name="label1" VerticalAlignment="Top" />
        <Label Content="Health Details" Height="28" HorizontalAlignment="Left" Margin="7,215,0,0" Name="label2" VerticalAlignment="Top" />

        <TextBox Height="23" HorizontalAlignment="Left" Margin="102,152,0,0" Name="txtID" VerticalAlignment="Top" Width="120" DataContext="{Binding ElementName=listView1,Path=SelectedItem}" Text="{Binding Path=ID}" IsReadOnly="True" Background="#26000000"></TextBox>
        <TextBox Height="23" HorizontalAlignment="Left" Margin="102,186,0,0" Name="txtName" VerticalAlignment="Top" Width="243" DataContext="{Binding ElementName=listView1,Path=SelectedItem}" Text="{Binding Path=Name}" />
        <ComboBox Height="23" HorizontalAlignment="Left" Margin="102,220,0,0" Name="cBHealthDetails" VerticalAlignment="Top" Width="120" DataContext="{Binding ElementName=listView1,Path=SelectedItem}" Text="{Binding Path=HealthDetails}">
            <ComboBoxItem Content="Yes" />
            <ComboBoxItem Content="No" />
        </ComboBox>
        <Button Content="New" Height="23" HorizontalAlignment="Left" Margin="25,262,0,0" Name="btnNew" VerticalAlignment="Top" Width="75" Click="btnNew_Click" />
        <Button Content="Insert" Height="23" HorizontalAlignment="Left" Margin="111,262,0,0" Name="btnInsert" VerticalAlignment="Top" Width="75" Click="btnInsert_Click"></Button>
        <Button Content="Update" Height="23" HorizontalAlignment="Left" Margin="197,262,0,0" Name="btnUpdate" VerticalAlignment="Top" Width="75" />
        <Button Content="Delete" Height="23" HorizontalAlignment="Left" Margin="280,262,0,0" Name="btnDelete" VerticalAlignment="Top" Width="75" />
        <Button Content="&lt;&lt;" Height="23" HorizontalAlignment="Left" Margin="25,301,0,0" Name="FirstRec" VerticalAlignment="Top" Width="75" Click="FirstRec_Click" />
        <Button Content="&lt;" Height="23" HorizontalAlignment="Left" Margin="111,301,0,0" Name="PreRec" VerticalAlignment="Top" Width="75" Click="PreRec_Click" />
        <Button Content="&gt;" Height="23" HorizontalAlignment="Right" Margin="0,301,112,0" Name="NxtRec" VerticalAlignment="Top" Width="75" Click="NxtRec_Click" />
        <Button Content="&gt;&gt;" Height="23" HorizontalAlignment="Left" Margin="280,301,0,0" Name="LastRec" VerticalAlignment="Top" Width="75" Click="LastRec_Click" />
        <Label Content="ID" Height="28" HorizontalAlignment="Left" Margin="11,147,0,0" Name="label3" VerticalAlignment="Top" />

    </Grid>
</Grid>

Huge Thanks

Update 1

Windows Loaded

private void Window_Loaded(object sender, RoutedEventArgs e)
    {
          ShowData();
    }


    void ShowData()
    {
        try
        {
            SqlCommand comm = new SqlCommand("Select * from tblTableB", mconn);
            DataTable dt = new DataTable();
            SqlDataAdapter da = new SqlDataAdapter(comm);
            da.Fill(dt);
            listView1.DataContext = dt.DefaultView;
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error: " + ex.Message);
        }
    }

    private void btnShowAll_Click(object sender, RoutedEventArgs e)
    {
        da = new SqlDataAdapter("select * from tblTableB", mconn);
        ds = new DataSet();
        da.Fill(ds, "tblTableB");
        da.Update(ds, "tblTableB");
        this.MaxRow();

        txtID.Text = ds.Tables[0].Rows[rno][0].ToString(); //rno["ID"]
        txtName.Text = ds.Tables[0].Rows[rno][1].ToString(); //rno["Name"] 
        cBHealthDetails.Text = ds.Tables[0].Rows[rno][2].ToString(); //also tried by replacing 
        //rno["HealthDetails"].ToString();
    }

XAML code

 <TextBox Height="23" HorizontalAlignment="Left" Margin="102,152,0,0" Name="txtID" VerticalAlignment="Top" Width="120" IsReadOnly="True" Background="#26000000"></TextBox>
        <TextBox Height="23" HorizontalAlignment="Left" Margin="102,186,0,0" Name="txtName" VerticalAlignment="Top" Width="243" />
        <ComboBox Height="23" HorizontalAlignment="Left" Margin="102,220,0,0" Name="cBHealthDetails" VerticalAlignment="Top" Width="120">
            <ComboBoxItem Content="Yes"></ComboBoxItem>
            <ComboBoxItem Content="No"></ComboBoxItem>
        </ComboBox>

So either there is a bug on wpf combox or for combox properties I need to do something which I have missed out. The only thing I did in the properties was...Items > Collections and added Content one for Yes and the other for No.

I still researching and I will update once the solution is found

Solution Found

It seems with wpf process or the architecture design is very different to winform particularly with combobox. The following code will not work

cBHealthDetails.Text = ds.Tables[0].Rows[rno][2].ToString();

I also have to use conditional loop to eliminate the duplicate values.

So the following piece of code worked for me for the combox which I found here and thanks to sohel khalifa...

 for (int intCount = 0; intCount < ds.Tables[0].Rows.Count; intCount++)
               {
                   var val = ds.Tables[0].Rows[intCount]["Health"].ToString();

                   //check if it already exists
                   if (!cbHealth.Items.Contains(val))
                   {
                       cbHealth.Items.Add(val);
                   }
               }

I did not even touch the xmal file to get the code working. In other words I did not code anything in xaml. I think most developers and/or end users prefer to use DataGrid.

3
static members or Non public members (this is when I position my cursor on ds.Table?bucketblast
mouse over txtID.Text is showing as "" next to the magnifier glass. When I click on the magnifier glass, Text Visualizer menu appears and for Expression it shows txtID.Text and Value nothing is there, it is emptybucketblast
@varocarbas, what part of the code looks fine? Have you even looked at it? The ComboBox in the question title does not even refer to a ComboBox! There are so many things wrong with this example.Sheridan
@Sheridan as you can see, my comment was written 24 days ago!!! The answer has been updated many times since then. Evidently if you see that the comment doesnot match the reality is because, perhaps (only perhaps), it does not refer to the same reality you are seeing right now. Thinking that what is evident for your is not evident for others is perhaps an a bit unrealistic assumption. I will delete my 24-day-old comments now. PS: "listview is not a combobox" is certainly wise, I wouldn't ever have seen this one.varocarbas
@varocarbas, that is a valid point that I had not thought of, although looking through the various edits to this post, I still can't see any 'fine looking' code. All the same, apologies.Sheridan

3 Answers

0
votes

I see a few ways this code could be improved. First, you shouldn't retrieve your data every time the navigation buttons are clicked. Second, there should be no need to set the Text of any of the controls in your code. They are all bound to the SelectedItem on the ListView. That means that when you change the ListView's SelectedItem, their values will update automatically.

You should load your data into a DataTable once (I'm assuming you do this in the Loaded event handler). And your navigation functions should look like:

private void PreRec_Click(object sender, RoutedEventArgs e)
{
    if (ds.Tables[0].Rows.Count > 0)
    {
        if (rno > 0)
        {
            rno--;
            listView1.SelectedItem = ds.Tables[0].Rows[rno];
        }
    }
}

From there, your Bindings will do all the work (as is the case when you click a row in the ListView).

0
votes

Your main problem is that you have set the ItemsSource for you ListView as "{Binding}"... this is binding to your whole MainWindow.cs class and not the data. Create a property for your data, bind to that instead and then you'll see data.

By the way, a ListView is not a ComboBox.

0
votes

I have updated at the top with a solution