Avatar billede janepigen Nybegynder
25. juli 2014 - 11:03 Der er 7 kommentarer

Databinding til textbokse i WPF (xaml)

Hej

Jeg prøver at lære C# og xaml i WPF, men jeg er ret ny i det. Så håber at der er nogle der kan hjælpe mig, da jeg ikke helt forstår forbindelserne. Jeg laver det i Visual Studio 2010.

Jeg vil gerne lave en databinding fra en SQL database til textboxe i WPF. Foreløbig har jeg fået en forbindelse op at køre med at loade data i et gridview, men jeg vil vise søgeresultatet i forskellige textboxe. Skal jeg så lave databinding til hver enkelt textbox og hvordan gør jeg det? Skal det være til binding path?


Her er min kode til at vise data i gridview grid1:

private void btnSoegPatienter_Click(object sender, RoutedEventArgs e)
            {
            hjerneskadeEntities dataEntities = new hjerneskadeEntities();

            try
            {
               
                ObjectQuery<T_Patient> patientSearch = dataEntities.T_Patient;

                if (SøgPatientTextBox != null || SøgPatientidTextBox != null)
                {
                    var query =
                        from T_Patient in patientSearch.AsEnumerable()
                        where (T_Patient.Efternavn == SøgPatientTextBox.Text || T_Patient.ID == SøgPatientidTextBox.Text.ToString())
                        select new { T_Patient.Type, T_Patient.Fornavn, T_Patient.Efternavn, T_Patient.Civilstand, T_Patient.Boforhold, T_Patient.Uddannelse, T_Patient.Alder, T_Patient.Køn };

                    dataGrid1.ItemsSource = query.ToList();
                }

                else
                {
                    MessageBox.Show("Søg på patientens efternavn eller ID");
                }
            }
            catch (SqlException ex)
            {
                MessageBox.Show(ex.Message);
                throw ex;
            }
        }



Her mit xaml kode:

<Grid DataContext="{StaticResource _T_PatientViewSource}" HorizontalAlignment="Left" Name="grid2" VerticalAlignment="Top">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>
                    <Label Style="{StaticResource MyLabel}" Content="Patientnr:" Grid.Column="0" Grid.Row="0" />
                        <TextBox Grid.Column="1" Grid.Row="0" Height="23" HorizontalAlignment="Left" Margin="5" Name="patientnrTextBox" Text="{Binding Path=Patientnr, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="150" />
                    <Label Style="{StaticResource MyLabel}" Content="Fornavn:" Grid.Column="0" Grid.Row="1" />
                        <TextBox Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="5" Name="fornavnTextBox" Text="{Binding Path=Fornavn, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="150" />
                    <Label Style="{StaticResource MyLabel}" Content="Efternavn:" Grid.Column="0" Grid.Row="2" />
                        <TextBox Grid.Column="1" Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="5" Name="efternavnTextBox" Text="{Binding Path=Efternavn, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="150" />
                    <Label Style="{StaticResource MyLabel}" Content="Fødselsdato:" Grid.Column="0" Grid.Row="3" />
                        <DatePicker Grid.Column="1" Grid.Row="3" Height="25" HorizontalAlignment="Left" Margin="5" Name="fødselsdatoDatePicker" SelectedDate="{Binding Path=Fødselsdato, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="150" />
                    <Label Style="{StaticResource MyLabel}" Content="Køn:" Grid.Column="0" Grid.Row="4" />
                        <TextBox Grid.Column="1" Grid.Row="4" Height="23" HorizontalAlignment="Left" Margin="5" Name="kønTextBox" Text="{Binding Path=Køn, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="150" />
                    <Label Style="{StaticResource MyLabel}" Content="CPR-Tjek:" Grid.Column="0" Grid.Row="5" />
                        <TextBox Grid.Column="1" Grid.Row="5" Height="23" HorizontalAlignment="Left" Margin="5" Name="_CPR_TjekTextBox" Text="{Binding Path=CPR-Tjek, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="150" />
                    </Grid>


På forhånd tak, Jane
Avatar billede crazysnap Seniormester
25. juli 2014 - 13:13 #1
Hej Jane,

Er det ét eller flere søgeresultater du vil binde til tekst-boksene? For hvis der altid kun er ét søgeresultat, kan du vel bare indsætte:

grid2.DataContext = query.FirstOrDefault();

i metoden 'btnSoegPatienter_Click'. Altså f.eks:

var lstRes = query.ToList();
dataGrid1.ItemsSource = lstRes;
grid2.DataContext = lstRes.FirstOrDefault();

Hvis der kan være flere søgeresultater og du derfor gerne ønsker x antal grid2'er, kan du proppe en ItemsControl rundt om grid2 og sætte DataContext på den i stedet - ligesom du gør med dataGrid1.

/CS
Avatar billede janepigen Nybegynder
25. juli 2014 - 15:33 #2
Hej CS
Mange tak for svar. Jeg ved ikke om jeg har forstået det helt, men i hvert fald ledte ItemsControl og din kode mig på sporet. Dog har jeg så fået et andet problem, da søgeresultatet bliver vist sådan

{Fornavn=bla bla, Efternavn=bla bla, Køn=bla bla}

Og det var jo ikke meningen - hvor går jeg mon galt i databindingen? Jeg har lavet Itemscontrol omkring mit grid der har tekstbokse, men søgeresultatet bliver vist som kode.

 
Xaml:
                            <ItemsControl Name="searchResult" ItemsSource="{Binding}">
                                    <Grid HorizontalAlignment="Left" Name="grid100" VerticalAlignment="Top">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto" />
                                            <ColumnDefinition Width="Auto" />
                                        </Grid.ColumnDefinitions>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto" />
                                            <RowDefinition Height="Auto" />
                                            <RowDefinition Height="Auto" />
                                        </Grid.RowDefinitions>
                                        <Label Style="{StaticResource MyLabel}" Content="Fornavn:" Grid.Column="0" Grid.Row="0" />
                                        <TextBox Grid.Column="1" Grid.Row="0" Height="23" HorizontalAlignment="Left" Margin="5" Name="fornavnTextBx" Text="{Binding Fornavn}" VerticalAlignment="Center" Width="150" />
                                        <Label Style="{StaticResource MyLabel}" Content="Efternavn:" Grid.Column="0" Grid.Row="1" />
                                        <TextBox Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="5" Name="efternavnTextBx" Text="{Binding Efternavn}" VerticalAlignment="Center" Width="150" />
                                        <Label Style="{StaticResource MyLabel}" Content="Køn:" Grid.Column="0" Grid.Row="2" />
                                        <TextBox Grid.Column="1" Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="5" Name="kønTextBx" Text="{Binding Køn}" VerticalAlignment="Center" Width="150" />
                                    </Grid>
                                </ItemsControl>

Query:

    ObjectQuery<T_Patient> patientSearch = dataEntities.T_Patient;
                searchResult.Items.Clear();
                if (SøgPatientTextBox != null || SøgPatientidTextBox != null)
                {
                    var query =
                        from T_Patient in patientSearch.AsEnumerable()
                        where (T_Patient.Efternavn == SøgPatientTextBox.Text || T_Patient.ID == SøgPatientidTextBox.Text.ToString())
                        select new { T_Patient.Fornavn, T_Patient.Efternavn, T_Patient.Køn };

                    dataGrid1.ItemsSource = query.ToList();
                    searchResult.ItemsSource = query;
                    var lstRes = query.ToList();
                    dataGrid1.ItemsSource = lstRes;
                    searchResult.DataContext = lstRes.FirstOrDefault();
                }

Mvh Jane
Avatar billede crazysnap Seniormester
25. juli 2014 - 16:21 #3
Hej Jane,

Du mangler et par ting. Angående din ItemsControl, gør følgende:

<ItemsControl Name="searchResult" >
  <ItemsControl.ItemsTemplate>
      <DataTemplate>
          <Grid Name="grid100" >
              .....
          </Grid>
      </DataTemplate>
  </ItemsControl.ItemsTemplate>
</ItemsControl>

Angående din 'btnSoegPatienter_Click'-metode, prøv følgende:

ObjectQuery<T_Patient> patientSearch = dataEntities.T_Patient;
searchResult.Items.Clear();
if (SøgPatientTextBox != null || SøgPatientidTextBox != null)
{
      var query = from T_Patient in patientSearch.AsEnumerable()
                  where (T_Patient.Efternavn == SøgPatientTextBox.Text || T_Patient.ID == SøgPatientidTextBox.Text.ToString())
                  select new { Fornavn = T_Patient.Fornavn, Efternavn = T_Patient.Efternavn, Køn = T_Patient.Køn };

    var lstRes = query.ToList();
    dataGrid1.ItemsSource = lstRes;
    searchResult.ItemsSource = lstRes;
}


/CS
Avatar billede crazysnap Seniormester
25. juli 2014 - 16:25 #4
Hej igen,

Jeg glemte at sige du jo også kan udvide din ItemsControl med ItemsPanel, På den måde kan du bestemme præcist hvordan dine søge-resultater skal listes. Så hvis du f.eks. tilføjer ItemsPanel som vist nedenfor, vil dine søge-resultater komme efter hinanden vertikalt:

<ItemsControl Name="searchResult" >

  <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
          <StackPanel Orientation="Vertical"></StackPanel>
      </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>

  <ItemsControl.ItemsTemplate>
      <DataTemplate>
          <Grid Name="grid100" >
              .....
          </Grid>
      </DataTemplate>
  </ItemsControl.ItemsTemplate>

</ItemsControl>

/CS
Avatar billede janepigen Nybegynder
28. juli 2014 - 11:41 #5
Hej CS

Mange tak for dit svar. Jeg beklager at jeg ikke har vendt tilbage før nu, men jeg kan desværre ikke teste det derhjemme.

Jeg er sikker på at din løsning virker, men jeg har foreløbig nogle problemer med exceptions. Jeg skriver nok senere, hvis jeg får det til at virke. Men jeg er som sagt ikke nogen haj til det. Din hjælp til Itemscontrol er meget værdsat :-)

Mvh Jane
Avatar billede janepigen Nybegynder
29. juli 2014 - 13:18 #6
Hej CS

Nu har jeg fået det til at virke med Itemscontrol. :-)

Min exception var  for øvrigt at jeg skulle binde Mode i Oneway og ikke i Twoway

Mange tak for din hjælp. Jeg er ikke helt sikker på hvordan det fungere med pointgivningen. Men jeg tror det er noget med at du skal give et svar og så kan jeg give dig point.

Mvh Jane
Avatar billede crazysnap Seniormester
29. juli 2014 - 14:11 #7
Hej Jane,

Det lyder rigtig godt. Og ja, som default er Mode = TwoWay for en binding. Så ja, du har helt ret, den kommer til at brokke sig når du kører programmet, da du binder en TextBox til en anonym type (altså new { T_Patient.Fornavn, T_Patient.Efternavn, T_Patient.Køn }). For man kan ikke ændre properties i anonyme typer (prøver du f.eks. at skrive noget i Fornavn-TextBox'en, vil den prøve at sætte Fornavn i den anynonyme type, til det du skriver - men det kan den jo så ikke).

Så det kan du løse ved at sætte Mode = OneWay på bindingen ja, eller bruge en Label/TextBlock i stedet for en TextBox.

Jeg samler ikke på point, så læg bare et svar selv du kan acceptere. :)

/CS
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester