combox wpf data not showing when I use navigation

2019-07-31 23:59发布

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条回答
虎瘦雄心在
2楼-- · 2019-08-01 00:26

I have updated at the top with a solution

查看更多
三岁会撩人
3楼-- · 2019-08-01 00:34

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.

查看更多
放我归山
4楼-- · 2019-08-01 00:53

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).

查看更多
登录 后发表回答