none
having a problem with bindings. please help....

    คำถาม

  • Hi. New to wpf so I'm a little lost was wondering if someone could help.....I have a project I'm working on.In my Project I have 1 Dataset (rdata) containing 3 tables, 1 parent table (Rtbl) and 2 child tables(Itbl & Dtbl) bound together by a foreign key (RtblId). In my project i have 2 list views ( LV1 & LV2). LV1 holds the data from Itbl, and LV2 holds the data from Dtbl. My problems are these..... It loads, however the Itbl and the Dtbl are displaying all the records, not just the records bound by the foreign keys.... In windows forms I used the binding sources, don't know how to do that here..... And I can't find any info that works...... So my question is how do I do it? Also I need to know how to insert and update the tables..... Now I can update the parent table fine. And if I delete the parent table the child table goes also..... but I cannot update the child tables or get them to display the data properly.....

    This is what i have so far:

    Imports System.Data.SqlClient

    Public Class AddRecipe
        Private rdata As New RDataSet
        Private tar As New RDataSetTableAdapters.RTblTableAdapter
        Private tai As New RDataSetTableAdapters.ITblTableAdapter
        Private tad As New RDataSetTableAdapters.DTblTableAdapter
        Private tamanager As New RDataSetTableAdapters.TableAdapterManager
        Private rview As CollectionView
        Private iview As CollectionView


        Private Sub AddRecipe_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
            Me.tarecipes.Fill(Me.recipesdata.RecipeTbl)
            Me.taingredients.Fill(Me.rdata.ITbl)
            Me.tad.Fill(Me.rdata.DTbl)
            Me.tamanager.RTblTableAdapter = tar

            Me.DataContext = Me.rdata.RTbl
            Me.ITblDataGrid.ItemsSource = rdata.ITbl
            Me.DTblDataGrid.ItemsSource = rdata.DTbl

            Me.rview = CollectionViewSource.GetDefaultView(Me.rdata.RTbl)
            Me.iview = CollectionViewSource.GetDefaultView(Me.rdata.ITbl)
        End Sub

        Private Sub btnSave_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles btnSave.Click
            Try
                If Me.rdata.HasChanges Then
                    If Me.tamanager.UpdateAll(Me.rdata) > 0 Then
                        MsgBox("Saved")
                    End If
                End If
            Catch ex As Exception
                MsgBox(ex.ToString)
            End Try
        End Sub

        Private Sub btnDelete_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles btnDelete.Click
            If Me.rview.CurrentPosition > -1 Then
                Dim recrow = CType(Me.rview.CurrentItem, System.Data.DataRowView).Row
                recrow.Delete()
            End If
        End Sub

        Private Sub btnBack_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles btnBack.Click
            If Me.rview.CurrentPosition > 0 Then
                Me.rview.MoveCurrentToPrevious()
            End If
        End Sub

        Private Sub btnNext_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles btnNext.Click
            If Me.rview.CurrentPosition < Me.recview.Count - 1 Then
                Me.rview.MoveCurrentToNext()
            End If
        End Sub
    End Class

    Any and all help with this would be greatly appreciated. Or if anyone knows of any links I could check out to figure it out, that would be awesome also.......

                                                                   Thanks


    Adam


    • แก้ไขโดย ajk825 27 เมษายน 2555 12:37
    27 เมษายน 2555 12:35

คำตอบ

  • Hey Adam,

    Your XAML didn't show up...but regardless, I totally understand liking a particular look, I've been in the same position many times...in terms of using an ObservableCollection, it's actually extremely straight forward (don't forget to add a using directive to System.Collections.ObjectModel)...here's a quick and extremely simple sample:

    ObservableCollection<string> oc = new ObservableCollection<string>();
    
    oc.Add("my string");

    In the above your collection would now have one string that said "my string", which could be bound directly to your ListView, and as you add items it would reflect automatically in your view since ObservableCollections implement property change notifiers - in your case you'd obviously want to create objects of the type you'd like to store, so something more like:

    ObservableCollection<Recipe> rc = new ObservableCollection<Recipe>(); Recipe r = new Recipe();

    r.RecipeName = "Squid Ink Pasta";

    r.Ingredients.Add("Flour"); r.Ingredients.Add("Eggs"); r.Ingredients.Add("Squid Ink"); rc.Add(r);

    then have your Recipe object look something like:

    public class Recipe
    {
        private ObservableCollection<string> ingredients = new ObservableCollection<string>();
    
        private string recipeName = string.Empty;
    
        public Recipe()
        {
        }
    
        public ObservableCollection<string> Ingredients
        {
            get
            {
                 return ingredients;
            }
    
            set
            {
                 ingredients = value;
            }
         }
    
        public string RecipeName
        {
            get
            {
                 return recipeName;
            }
    
            set
            {
                 recipeName = value;
            }
         }
    }

    In your case since you have one parent (guessing that's the recipe), and numerous children, you'd just add more collections to your recipe object and have them be accessible in a similar manner to the ingredients.  Then your binding becomes trivial, you'd just bind your recipe collection to your listview then bind each child listview to the property of the recipe you wanted displayed, each of which presumably would be a collection of their own.

    Hope that makes more sense,

    Aj


    If at first you don't succeed, skydiving is definitely not for you!

    • เสนอเป็นคำตอบโดย aaj23 27 เมษายน 2555 15:26
    • ทำเครื่องหมายเป็นคำตอบโดย ajk825 29 เมษายน 2555 1:09
    27 เมษายน 2555 15:23

ตอบทั้งหมด

  • Hey Adam,

    While DataTables and DataSets still have their place in WPF, the thing that makes WPF really great is its binding engine which is really more geared toward the binding of objects.  Might I suggest you switch to ObservableCollections rather than tables, this way you can create a "Recipe" object and an "Ingredients" object, you could then have a collection of recipes that each contain a collection of ingredients...it not only makes more sense logically than two separate data sources, it'll be easier for you to implement.  In either case, whether you switch to objects or stick with tables, if you set your binding mode to TwoWay it'll update your underlying source for you automatically when you change the values in the view (I'd need to see your XAML to give you any help with that).  In terms of Inserts/Deletes...the concept again is basically the same, you'd just add to or remove from the underlying table/object which would be reflected in your view automatically...well, sorta...with observable collections, it implements property change notifications for you, datatables I believe do not so you'd have to refresh your binding.

    From that point I'd then ask, do you really need two listviews?  Perhaps expand/collapse the listviewitems to show/hide the ingredients, or maybe use a HierarchicalDataTemplate and put your entries into a treeview that you could style...in either case, you'd have one less control to work with and give your users a single place to look, not to mention the ability to have more than one recipe open at a time.  A little more background would help if I didn't come close to answering your question.

    Hope it helps,

    Aj


    If at first you don't succeed, skydiving is definitely not for you!

    27 เมษายน 2555 13:52
  • well i appreciate the help.... here's part of my xaml, it's really long so i only added the first part:<Window x:Class="AddRecipe"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="" Height="750" Width="1000" WindowStartupLocation="CenterScreen" WindowStyle="None" FontFamily="Georgia" FontSize="15" FontWeight="Bold" ResizeMode="NoResize" ShowActivated="True" ShowInTaskbar="False" AllowDrop="True" Name="AddRecipe">
        <Window.Background>
            <ImageBrush ImageSource="/MRB;component/Images/Books.jpg" />
        </Window.Background>
        <Window.BorderBrush>
            <SolidColorBrush />
        </Window.BorderBrush>
        <Grid Width="1000" Height="750">
            <TabControl Height="640" HorizontalAlignment="Left" Margin="12,12,0,0" Name="TabControl1" VerticalAlignment="Top" Width="954">
                <TabControl.BorderBrush>
                    <SolidColorBrush />
                </TabControl.BorderBrush>
                <TabControl.Background>
                    <SolidColorBrush />
                </TabControl.Background>
                <TabItem Name="RecipesTab" Height="10" Width="20">
                    <Grid Height="627" Name="RecipesGrid">
                        <Grid HorizontalAlignment="Left" Margin="40,32,0,0" Name="Grid4" VerticalAlignment="Top" Width="425" Height="71">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="425" />
                                <ColumnDefinition Width="0" />
                                <ColumnDefinition Width="0*" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="40" />
                                <RowDefinition Height="19*" />
                            </Grid.RowDefinitions>
                            <TextBox Height="30" HorizontalAlignment="Left" Margin="6,5,0,4" Name="RecipeNameTextBox" Text="{Binding Path=RecipeName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="413" FontSize="16" VerticalContentAlignment="Center" />
                            <Label Content="Recipe Name" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1" FontSize="15" FontFamily="Georgia" FontStyle="Italic" FontWeight="Bold" HorizontalContentAlignment="Left" Foreground="#FFCB3131" />
                        </Grid>
                        <Grid HorizontalAlignment="Left" Margin="37,121,0,0" Name="Grid5" VerticalAlignment="Top" Width="267" Height="40">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="239*" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="34*" />
                            </Grid.RowDefinitions>
                            <Label Content="Servings" HorizontalAlignment="Left" Margin="3,6,0,0" VerticalAlignment="Top" FontFamily="Georgia" FontSize="15" FontStyle="Italic" FontWeight="Bold" Foreground="#FFCB3131" />
                            <TextBox Grid.Column="1" Height="27" HorizontalAlignment="Left" Margin="3,3,0,0" Name="ServingsTextBox" Text="{Binding Path=Servings, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="174" HorizontalContentAlignment="Left" VerticalContentAlignment="Center" />
                        </Grid>
                        <Grid Margin="120,178,0,0" Name="Grid6" HorizontalAlignment="Left" Width="139" Height="62" VerticalAlignment="Top">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="139*" />
                            </Grid.ColumnDefinitions>
                            <TextBox Grid.Column="1" Height="27" Margin="3,3,0,0" Name="PrepTimeTextBox" Text="{Binding Path=PrepTime, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Top" HorizontalAlignment="Left" Width="130" VerticalContentAlignment="Center" />
                            <Label Content="Prep Time" HorizontalAlignment="Left" Margin="2,32,0,0" VerticalAlignment="Top" FontWeight="Bold" FontStyle="Italic" FontFamily="Georgia" FontSize="15" Grid.Column="1" Height="30" Foreground="#FFCB3131" />
                        </Grid>
                        <Grid HorizontalAlignment="Left" Margin="53,261,0,0" Name="Grid8" VerticalAlignment="Top">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Label Content="Calories" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" FontSize="15" FontFamily="Georgia" FontStyle="Italic" FontWeight="Bold" Foreground="#FF4E4EC4" />
                            <TextBox Grid.Column="1" Grid.Row="0" Height="23" HorizontalAlignment="Left" Margin="3" Name="CaloriesTextBox" Text="{Binding Path=Calories, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="85" VerticalContentAlignment="Center" />
                        </Grid>
                        <Grid HorizontalAlignment="Left" Margin="59,322,0,0" Name="Grid9" VerticalAlignment="Top">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Label Content="Protein" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" FontSize="15" FontFamily="Georgia" FontStyle="Italic" FontWeight="Bold" Foreground="#FF4E4EC4" />
                            <TextBox Grid.Column="1" Grid.Row="0" Height="23" HorizontalAlignment="Left" Margin="3" Name="ProteinTextBox" Text="{Binding Path=Protein, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="85" VerticalContentAlignment="Center" />
                        </Grid>
                        <Grid HorizontalAlignment="Left" Margin="95,378,0,0" Name="Grid10" VerticalAlignment="Top" Height="33">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Label Content="Fat" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" FontSize="15" FontFamily="Georgia" FontStyle="Italic" FontWeight="Bold" Foreground="#FF4E4EC4" />
                            <TextBox Grid.Column="1" Grid.Row="0" Height="23" HorizontalAlignment="Left" Margin="3" Name="FatTextBox" Text="{Binding Path=Fat, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="85" VerticalContentAlignment="Center" />
                        </Grid>
                        <Grid HorizontalAlignment="Left" Margin="296,320,0,0" Name="Grid11" VerticalAlignment="Top">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Label Content="Sodium" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" FontSize="15" FontFamily="Georgia" FontStyle="Italic" FontWeight="Bold" Foreground="#FF4E4EC4" />
                            <TextBox Grid.Column="1" Grid.Row="0" Height="23" HorizontalAlignment="Left" Margin="3" Name="SodiumTextBox" Text="{Binding Path=Sodium, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="85" VerticalContentAlignment="Center" />
                        </Grid>
                        <Grid HorizontalAlignment="Left" Margin="309,261,0,0" Name="Grid12" VerticalAlignment="Top">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Label Content="Carbs" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" FontSize="15" FontFamily="Georgia" FontStyle="Italic" FontWeight="Bold" Foreground="#FF4E4EC4" />
                            <TextBox Grid.Column="1" Grid.Row="0" Height="23" HorizontalAlignment="Left" Margin="3" Name="CarbsTextBox" Text="{Binding Path=Carbs, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="85" VerticalContentAlignment="Center" />
                        </Grid>
                        <Grid HorizontalAlignment="Left" Margin="266,377,0,0" Name="Grid13" VerticalAlignment="Top">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Label Content="Cholesterol" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" FontSize="15" FontFamily="Georgia" FontStyle="Italic" FontWeight="Bold" Foreground="#FF4E4EC4" />
                            <TextBox Grid.Column="1" Grid.Row="0" Height="23" HorizontalAlignment="Left" Margin="3" Name="CholesterolTextBox" Text="{Binding Path=Cholesterol, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="85" VerticalContentAlignment="Center" />
                        </Grid>
                        <Grid HorizontalAlignment="Left" Margin="90,447,0,0" Name="Grid14" VerticalAlignment="Top">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Label Content="Egg Allergy" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" FontSize="15" FontFamily="Georgia" FontStyle="Italic" FontWeight="Bold" Foreground="#FF339333" />
                            <CheckBox Content="" Grid.Column="1" Grid.Row="0" Height="16" HorizontalAlignment="Left" IsChecked="{Binding Path=EggAllergy, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" Margin="3" Name="EggAllergyCheckBox" VerticalAlignment="Center" />
                        </Grid>
                        <Grid HorizontalAlignment="Left" Margin="74,498,0,0" Name="Grid15" VerticalAlignment="Top">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Label Content="Dairy Allergy" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" FontSize="15" FontFamily="Georgia" FontStyle="Italic" FontWeight="Bold" Foreground="#FF339333" />
                            <CheckBox Content="" Grid.Column="1" Grid.Row="0" Height="16" HorizontalAlignment="Left" IsChecked="{Binding Path=DairyAllergy, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" Margin="3" Name="DairyAllergyCheckBox" VerticalAlignment="Center" />
                        </Grid>
                        <Grid HorizontalAlignment="Left" Margin="91,549,0,0" Name="Grid16" VerticalAlignment="Top">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Label Content="Soy Allergy" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" FontSize="15" FontFamily="Georgia" FontStyle="Italic" FontWeight="Bold" Foreground="#FF339333" />
                            <CheckBox Content="" Grid.Column="1" Grid.Row="0" Height="16" HorizontalAlignment="Left" IsChecked="{Binding Path=SoyAllergy, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" Margin="3" Name="SoyAllergyCheckBox" VerticalAlignment="Center" />
                        </Grid>
                        <Grid HorizontalAlignment="Left" Margin="304,549,0,0" Name="Grid17" VerticalAlignment="Top">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Label Content="Wheat Allergy" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" FontSize="15" FontFamily="Georgia" FontStyle="Italic" FontWeight="Bold" Foreground="#FF339333" />
                            <CheckBox Content="" Grid.Column="1" Grid.Row="0" Height="16" HorizontalAlignment="Left" IsChecked="{Binding Path=WheatAllergy, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" Margin="3" Name="WheatAllergyCheckBox" VerticalAlignment="Center" />
                        </Grid>
                        <Grid HorizontalAlignment="Left" Margin="292,498,0,0" Name="Grid18" VerticalAlignment="Top">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Label Content="Seafood Allergy" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" FontSize="15" FontFamily="Georgia" FontStyle="Italic" FontWeight="Bold" Foreground="#FF339333" />
                            <CheckBox Content="" Grid.Column="1" Grid.Row="0" Height="16" HorizontalAlignment="Left" IsChecked="{Binding Path=SeafoodAllergy, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" Margin="3" Name="SeafoodAllergyCheckBox" VerticalAlignment="Center" />
                        </Grid>
                        <Grid HorizontalAlignment="Left" Margin="286,447,0,0" Name="Grid19" VerticalAlignment="Top">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Label Content="Nut Seed Allergy" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" FontSize="15" FontStyle="Italic" FontWeight="Bold" FontFamily="Georgia" Foreground="#FF339333" />
                            <CheckBox Content="" Grid.Column="1" Grid.Row="0" Height="16" HorizontalAlignment="Left" IsChecked="{Binding Path=NutSeedAllergy, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" Margin="3" Name="NutSeedAllergyCheckBox" VerticalAlignment="Center" />
                        </Grid>
                        <Grid HorizontalAlignment="Left" Margin="317,177,0,0" Name="Grid7" VerticalAlignment="Top" Height="62" Width="142">
                            <Label Content="Bake Time" HorizontalAlignment="Left" Margin="0,30,0,0" VerticalAlignment="Top" FontFamily="Georgia" FontSize="15" FontStyle="Italic" FontWeight="Bold" Height="30" Foreground="#FFCB3131" />
                            <TextBox Height="27" Margin="6,4,0,0" Name="BakeTimeTextBox" Text="{Binding Path=BakeTime, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Top" HorizontalAlignment="Left" Width="130" VerticalContentAlignment="Center" />
                        </Grid>
                        <StackPanel HorizontalAlignment="Right" Margin="0,44,36,308" Name="StackPanel1" Width="380">
                            <DataGrid AutoGenerateColumns="False" Background="White" BorderBrush="Coral" CanUserReorderColumns="False" CanUserResizeColumns="False" CanUserResizeRows="False" CanUserSortColumns="False" ColumnHeaderHeight="25" EnableRowVirtualization="True" FontSize="14" GridLinesVisibility="None" HeadersVisibility="Column" Height="274" IsSynchronizedWithCurrentItem="True" Name="IngredientsTblDataGrid" RowDetailsVisibilityMode="Visible" RowHeaderWidth="0" Width="380">
                                <DataGrid.Columns>
                                    <DataGridTextColumn x:Name="IngredientIDColumn" Binding="{Binding Path=IngredientID}" CanUserReorder="False" Header="Ingredient ID" IsReadOnly="True" Visibility="Hidden" Width="SizeToHeader" />
                                    <DataGridTextColumn x:Name="AmountColumn" Binding="{Binding Path=Amount}" CanUserReorder="False" Header="Amount" MinWidth="85" Width="85" />
                                    <DataGridTextColumn x:Name="IngredientColumn" Binding="{Binding Path=Ingredient}" CanUserReorder="False" Header="Ingredient" MinWidth="298" Width="298" />
                                    <DataGridTextColumn x:Name="RecipeIDColumn" Binding="{Binding Path=RecipeID}" CanUserReorder="False" Header="Recipe ID" IsReadOnly="True" Visibility="Hidden" Width="SizeToHeader" />
                                </DataGrid.Columns>
                            </DataGrid>
                        </StackPanel>
                        <StackPanel HorizontalAlignment="Right" Margin="0,325,36,27" Name="StackPanel2" Width="380">
                            <DataGrid AutoGenerateColumns="False" Background="White" BorderBrush="Coral" CanUserReorderColumns="False" CanUserResizeColumns="False" CanUserResizeRows="False" CanUserSortColumns="False" ColumnHeaderHeight="25" EnableRowVirtualization="True" FontSize="14" GridLinesVisibility="None" Height="276" Name="DirectionsTblDataGrid" RowDetailsVisibilityMode="Visible" RowHeaderWidth="0" Width="380" IsSynchronizedWithCurrentItem="True">
                                <DataGrid.Columns>
                                    <DataGridTextColumn x:Name="DirectionIDColumn" Binding="{Binding Path=DirectionID}" CanUserReorder="False" Header="Direction ID" IsReadOnly="True" Visibility="Hidden" Width="SizeToHeader" />
                                    <DataGridTextColumn x:Name="DirectionsColumn" Binding="{Binding Path=Directions}" CanUserReorder="False" Header="Directions" MinWidth="382" Width="382" />
                                    <DataGridTextColumn x:Name="RecipeIDColumn1" Binding="{Binding Path=RecipeID}" CanUserReorder="False" Header="Recipe ID" IsReadOnly="True" Visibility="Hidden" Width="SizeToHeader" />
                                </DataGrid.Columns>
                            </DataGrid>
                        </StackPanel>

    Not quite sure what ya mean by ObservableCollections but i'm sure their are tutorials or something about it....... well thanks again. going to work so i'll try it when i get home. also i don't know c# so please use vb examples if you have any... or if ya know where to find some theat would be awesome too.... thanks


    Adam

    27 เมษายน 2555 15:05
  • Hey Adam,

    Your XAML didn't show up...but regardless, I totally understand liking a particular look, I've been in the same position many times...in terms of using an ObservableCollection, it's actually extremely straight forward (don't forget to add a using directive to System.Collections.ObjectModel)...here's a quick and extremely simple sample:

    ObservableCollection<string> oc = new ObservableCollection<string>();
    
    oc.Add("my string");

    In the above your collection would now have one string that said "my string", which could be bound directly to your ListView, and as you add items it would reflect automatically in your view since ObservableCollections implement property change notifiers - in your case you'd obviously want to create objects of the type you'd like to store, so something more like:

    ObservableCollection<Recipe> rc = new ObservableCollection<Recipe>(); Recipe r = new Recipe();

    r.RecipeName = "Squid Ink Pasta";

    r.Ingredients.Add("Flour"); r.Ingredients.Add("Eggs"); r.Ingredients.Add("Squid Ink"); rc.Add(r);

    then have your Recipe object look something like:

    public class Recipe
    {
        private ObservableCollection<string> ingredients = new ObservableCollection<string>();
    
        private string recipeName = string.Empty;
    
        public Recipe()
        {
        }
    
        public ObservableCollection<string> Ingredients
        {
            get
            {
                 return ingredients;
            }
    
            set
            {
                 ingredients = value;
            }
         }
    
        public string RecipeName
        {
            get
            {
                 return recipeName;
            }
    
            set
            {
                 recipeName = value;
            }
         }
    }

    In your case since you have one parent (guessing that's the recipe), and numerous children, you'd just add more collections to your recipe object and have them be accessible in a similar manner to the ingredients.  Then your binding becomes trivial, you'd just bind your recipe collection to your listview then bind each child listview to the property of the recipe you wanted displayed, each of which presumably would be a collection of their own.

    Hope that makes more sense,

    Aj


    If at first you don't succeed, skydiving is definitely not for you!

    • เสนอเป็นคำตอบโดย aaj23 27 เมษายน 2555 15:26
    • ทำเครื่องหมายเป็นคำตอบโดย ajk825 29 เมษายน 2555 1:09
    27 เมษายน 2555 15:23
  • Oh sorry, I usually write in C# so my VB is always a little messy if I'm not writing in VS to correct my mistakes...here's a good resource for you though:

    http://converter.telerik.com/

    That will convert C# to VB and vice versa.


    If at first you don't succeed, skydiving is definitely not for you!

    27 เมษายน 2555 15:32
  • Hi aaj23 sorry about the delay in response, just getting home from work. Tried out the converter...  pretty cool. It's gonna help a lot seeing as most the code samples I see are in c#. Haven't tried out the Observable Collection idea yet... I will, real soon, and I'll let ya know how it works out...Thanks. The tables are bound by RecipeID's, is that the same concept you have with the r.RecipeName above? Sorry... I'm a noob. One more question though.... would this concept be easier as a dataset, or a dataset entity?

                                               Thanks again.


    Adam

    28 เมษายน 2555 1:36
  • Ok I took a look at the MSN library and found the ObservableCollections section.... Now in my original try for this project, I've tried 3 or 4 different approaches to this. I tried something along this line (I added the clr-namespace:  part) , again I used CollectionView's.... But I also used CollectionViewSource's and instead of :

      Me.rview = CollectionViewSource.GetDefaultView(Me.rdata.RTbl)
            Me.iview = CollectionViewSource.GetDefaultView(Me.rdata.ITbl)

    I used them as cast types:

    recviews = CType(Me.FindResource("RecipeTblViewSource"), CollectionViewSource)
            ingviews = CType(Me.FindResource("RecipeTblIngredientsTblViewSource"), CollectionViewSource)
            dirviews = CType(Me.FindResource("RecipeTblDirectionsTblViewSource"), CollectionViewSource)

    this allows me to use the 'FK_RecipeTbl_IngredientsTbl' restraint I created when I created the tables. And it works great, almost. Everything binds properly. I can navigate through my records and everything is where it should be as fart as foreign keys go.....

    However Add, insert, update and delete give me this message and I have no idea how to fix it...

    system.Application exception: Table adapter manager contains no connection information. Set each table adapter manager to a valid table adapter instance.

    what does that mean and how do I fix it? If I can get the Add, Insert, Delete and Update working this part of my headache is over... Sorry. I know this is way off my original question, but your response drew me back to this.

    Anyways any thoughts or help? I really appreciate it.


    Adam


    • แก้ไขโดย ajk825 28 เมษายน 2555 3:05
    28 เมษายน 2555 3:05
  • Hey Adam,

    You're massively over-thinking things with regard to the ObservableCollections...they're actually concentric in a manner of speaking.  So you have an ObservableCollection of Recipe objects (I just added a name to each object as I assumed you'd have a name for each of your recipes) and within each Recipe object you can place Ingredients, Instructions, etc, each of which could conceivable have their own properties and or collections (you can put an object or an ObservableCollection of objects inside an object which itself is already an item within an ObservableCollection)...to draw a parallel that you may be more familiar with, think of it like having a DataTable stored inside a cell of another DataTable...so rather than having foreign keys you actually put the entire referenced DataTable where the foreign key value would be...this way when you do your binding to your view, you don't need to worry about relationships and so on because it's implicit in its design - that said, although you could actually do that with DataTables it's impractical from a design perspective, which is why objects are so handy, you can essentially create whatever your desire and really customize it to your purpose...this is what makes object oriented programming such a great thing.  If you plan to work with WPF over the long run, or any OOP language, you'll definitely want to read up on objects a little more...you'll find binding, manipulation, etc. in WPF, Java, etc. is just simply easier using objects rather than flat tables.  It adds a layer of complexity in terms of comprehension and will change the way you do a lot of things, but after you get a firm grasp of it, you'll find it's a great tool to add to your bag.

    Regarding your error, it's tough to guess without really being more familiar with your project but if I had to guess; I'd say you probably used a 'where' clause in your data adapter or selected multiple tables in the same adapter, thus writing back to your source (guessing a database of some flavor) is not transparent to the adapter...think of it like when you were using WinForms...if you tried to put a where clause or multiple tables it would create the select adapter for you, but it'd pitch a fit when trying to create the updates, inserts, and deletes.  All that said, post that as a separate question, this way you can post your code and get more feedback, as I'm sure there are many people on the forums more familiar with your issue (not one I've dealt with).

    Hope it helps,

    Aj

    (please don't forget to mark anything helpful that was and or mark an answer)


    If at first you don't succeed, skydiving is definitely not for you!

    28 เมษายน 2555 13:22
  • one more question, sorry...... if i do put all the tables into 1  observable collection how do i write this part in code?

    Private Sub Window_Loaded() Handles MyBase.Loaded
    
        Dim query = From c In db.RecipeTbl.Include("IngredientsTbl") _
                    Select c

    I'm not sure how to query all the tables in the Include statement. Or do I do that individually also?


    Adam

    1 พฤษภาคม 2555 5:56
  • hey aj.... i'm working on the observational collection as i type this... pretty nifty tool. thanks for the heads up. quick question...... for the observational collection part... should i make an observational collection for each of the child tables or just 1 collection for all 8 tables? i'm watching beth massi's tutorial on it  and she doesn't really say... shows how to set it up but only uses 1 child in the example so i don't know.... thanks again for the help....

    Adam

    1 พฤษภาคม 2555 5:57
  • Hey Adam,

    Well, I don't normally use DataTables in ObservableCollections, but if you're gonna go that route, I'd just create one ObservableCollection of an object and use public properties to expose your tables from that object.  That said...I think you're sorta missing the bus on ObservableCollections - although they can hold DataTables, you'll see them most used with objects...I did a short example, and although I didn't populate my data from a real source, you'll get the gist (more past the code):

    namespace MyRecipeBook
    {
        using System;
        using System.Collections.ObjectModel;
        using System.Data;
        using System.Data.SqlClient;
    
        public class Recipe
        {
            private string recipeID = string.Empty;
            private string recipeName = string.Empty;
            private int estimatedPreparationTimeInMinutes = 0;
            private string recipeAuthor = string.Empty;
            private ObservableCollection<Ingredient> ingredients = new ObservableCollection<Ingredient>();
            private ObservableCollection<Instruction> instructions = new ObservableCollection<Instruction>();
    
            public Recipe(){ }
    
            public string RecipeID
            {
                get { return this.recipeID; }
                set { this.recipeID = value; }
            }
    
            public string RecipeName
            {
                get { return this.recipeName; }
                set { this.recipeName = value; }
            }
    
            public int EstimatedPreparationTimeInMinutes
            {
                get { return this.estimatedPreparationTimeInMinutes; }
                set { this.estimatedPreparationTimeInMinutes = value; }
            }
    
            public string RecipeAuthor
            {
                get { return this.recipeAuthor; }
                set { this.recipeAuthor = value; }
            }
    
            public ObservableCollection<Ingredient> Ingredients
            {
                get { return this.ingredients; }
                set { this.ingredients = value; }
            }
    
            public ObservableCollection<Instruction> Instructions
            {
                get { return this.instructions; }
                set { this.instructions = value; }
            }
        }
    
        public class Ingredient
        {
            private string ingredientName = string.Empty;
            private string preferredBrandName = string.Empty;
            private decimal approximateCost = new decimal(0.0);
    
            public Ingredient(){ }
    
            public string IngredientName
            {
                get { return this.ingredientName; }
                set { this.ingredientName = value; }
            }
    
            public string PreferredBrandName
            {
                get { return this.preferredBrandName; }
                set { this.preferredBrandName = value; }
            }
    
            public decimal ApproximateCost
            {
                get { return this.approximateCost; }
                set { this.approximateCost = value; }
            }
        }
    
        public class Instruction
        {
            private string instructionName = string.Empty;
            private string preferredMethod = string.Empty;
            private int approximateTimeToCompleteInMinutes = 0;
    
            public Instruction() { }
    
            public string InstructionName
            {
                get { return this.instructionName; }
                set { this.instructionName = value; }
            }
    
            public string PreferredMethod
            {
                get { return this.preferredMethod; }
                set { this.preferredMethod = value; }
            }
    
            public int ApproximateTimeToCompleteInMinutes
            {
                get { return this.approximateTimeToCompleteInMinutes; }
                set { this.approximateTimeToCompleteInMinutes = value; }
            }
        }
        
        public class RecipeList
        {
            private ObservableCollection<Recipe> recipes = new ObservableCollection<Recipe>();
    
            public RecipeList()
            { }
    
            public ObservableCollection<Recipe> Recipes
            {
                get { return this.recipes; }
                set { this.recipes = value; }
            }
    
        }
    
        public class MyMainClass
        {
            public MyMainClass()
            {
                RecipeList rl = this.LoadMyRecipeBook();
                this.DataContext = rl;
            }
    
            private RecipeList LoadMyRecipeBook()
            {
                RecipeList rl = new RecipeList();
    
                Recipe r = new Recipe();
                r.RecipeID = "23";
                r.RecipeAuthor = "AJ";
                r.RecipeName = "AJ's Chillean Sea Bass";
                r.EstimatedPreparationTimeInMinutes = 80;
    
                r.Ingredients.Add(new Ingredient() { ApproximateCost = new decimal(26.99), IngredientName = "Chillean Sea Bass", PreferredBrandName = "N/A" });
                r.Ingredients.Add(new Ingredient() { ApproximateCost = new decimal(2.50), IngredientName = "Fresh Ginger Root", PreferredBrandName = "N/A" });
                r.Ingredients.Add(new Ingredient() { ApproximateCost = new decimal(6.00), IngredientName = "Shoyu/Tamari", PreferredBrandName = "Kikoman" });
    
                r.Instructions.Add(new Instruction { ApproximateTimeToCompleteInMinutes = 5, InstructionName = "Scale Fish", PreferredMethod = "Using a fish scaler" });
                r.Instructions.Add(new Instruction { ApproximateTimeToCompleteInMinutes = 3, InstructionName = "Create Marinade", PreferredMethod = "Using a large bowl" });
    
                rl.Recipes.Add(r);
    
                return rl;
            }
        }
    }
    

    What you end up with is a list of recipes that itself contains the actual recipes which each contain a list of ingredients and instructions.  It would be as if you were actually looking at a cookbook, the book would be your RecipeList object, each page would be a Recipe object, and each page would have a list of Ingredient and Instruction objects...with DataTables it would be more akin to having several books, one with the recipe names, one with the recipe ingredients, and one with the recipe instructions, each having just a page number reference to the other book where the corresponding information could be found.

    With my above example, it's about as clear as mud how powerful this is and how much easier it makes things when you start to do more complex bindings...but trust me on the sunscreen...or, objects in this case.  If you want to see a really stellar working example of this, check out Bea Stollnitz example - http://bea.stollnitz.com/blog/?p=40 where she takes a pretty simple set of data and really does amazing things with it.

    Anyway, hope it all helps,

    Aj


    If at first you don't succeed, skydiving is definitely not for you!

    1 พฤษภาคม 2555 14:45