דילוג לתוכן
  • דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום
כיווץ
תחומים

תחומים - פורום חרדי מקצועי

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
  1. דף הבית
  2. תכנות
  3. ארכיון code613m
  4. WPF לחצן '+' בראש שורה בדטה-גריד

WPF לחצן '+' בראש שורה בדטה-גריד

מתוזמן נעוץ נעול הועבר ארכיון code613m
10 פוסטים 2 כותבים 668 צפיות
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • רחמיםר מנותק
    רחמיםר מנותק
    רחמים מורחק
    כתב ב נערך לאחרונה על ידי
    #1

    אני מנסה ליצור לחצן בראש השורה בדטה-גריד בדומה למה שיש באקסס שלחצן זה יציג ויסתיר את גליון הנתונים המשני מה שנקרא ב WPF:
    RowDetails

    אולם כאשר עשיתי טמפלט ראש השורה כזה:

    <DataGrid.RowHeaderTemplate>
        <DataTemplate>
            <Button Content="+" Click="Button_Click"> 
            </Button>
        </DataTemplate>
    </DataGrid.RowHeaderTemplate>
    

    לא ידעתי איך אני מגיע דרך ארוע הלחיצה לשורה שבה צריך לפתוח את גליון המשנה.

    Private Sub Button_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
        Dim btn As Button = DirectCast(sender, Button)
        Dim row As DataGridRow = ???
        If btn.Content = "+" Then
            btn.Content = "-"
        Else
            btn.Content = "+"
        End If
    End Sub
    

    תודה לכולם,
    ושבוע טוב.

    פורסם במקור בפורום CODE613 ב21/12/2013 20:13 (+02:00)

    תגובה 1 תגובה אחרונה
    0
    • dovidD מחובר
      dovidD מחובר
      dovid ניהול
      כתב ב נערך לאחרונה על ידי
      #2

      בWPF מקובל מאוד לא לעשות כמו שהראית, ממילא זה גם מסובך לגמרי.
      מה שמקובל זה בינדינג בין הכפתור לנראות של הפירוט.
      זה מסובך קצת, כי הכפתור חסר מצב, אז צריך להשתמש בToggleButton.
      כמו"כ מוכרחים קונוורטר מבולאני לויסיבליטי.

      זה נראה פי כמה מסובך ממה שאמור להיות, אבל מנסיון, זה הרבה יותר נוח ומסודר לטווח ארוך.
      אם יהיה לי זמן, מחר אעלה את קוד שעושה זאת.

      פורסם במקור בפורום CODE613 ב22/12/2013 21:06 (+02:00)

      מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

      בכל נושא אפשר ליצור קשר dovid@tchumim.com

      תגובה 1 תגובה אחרונה
      0
      • רחמיםר מנותק
        רחמיםר מנותק
        רחמים מורחק
        כתב ב נערך לאחרונה על ידי
        #3

        בסוף מצאתי משהו כזה:
        קוד ה XAML נשאר אותו דבר, ורק עוד כמה שורות שיופעלו בלחיצה על הלחצן:

        Private Sub Button_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
        
                Dim btn As Button = DirectCast(sender, Button)
                Dim DC = DirectCast(DirectCast(btn.TemplatedParent, ContentPresenter).Parent, StackPanel).DataContext
                Dim FileOrFolder As FileOrFolder = DirectCast(DC, FileOrFolder)
                Dim dr As DataGridRow = DirectCast(dataGrid1.ItemContainerGenerator.ContainerFromItem(FileOrFolder), DataGridRow)
        
                If btn.Content = "+" Then
                    dr.DetailsVisibility = Windows.Visibility.Visible
                    btn.Content = Chr(150) ' מקף ארוך יותר מסימן '-' מינוס
                Else
                    btn.Content = "+"
                    dr.DetailsVisibility = Windows.Visibility.Collapsed
                End If
        
            End Sub
        

        אם יש משהו יותר טוב לטווח הקצר ו/או הארוך אשמח לשומע.
        תודה רבה.

        פורסם במקור בפורום CODE613 ב22/12/2013 21:59 (+02:00)

        תגובה 1 תגובה אחרונה
        0
        • רחמיםר מנותק
          רחמיםר מנותק
          רחמים מורחק
          כתב ב נערך לאחרונה על ידי
          #4

          עכשיו הגעתי לחלק הקשה...
          אני צריך להיות מסוגל להכניס לכל דטה-רוב טמפלט אחר של DetailsTemplate, וזה לא בעיה אם הטמפלט היה איזה פקדים פשוטים, אבל מה שאני לא יודע איך להכניס לטמפלט את גליון הנתונים שיצרתי שהוא למעשה פקד מסוג UserControl שיש בו רק דטה-גריד אחד אבל הוא צריך לקבל פרמטרים בבנאי וגם הוא OF TRecord
          בקיצור: בקוד דלעיל אחרי שורה 10 צריך להכניס עוד שורה כזו:

              dr.DetailsTemplate = GetRowDetailsTemplate(DC.ID)
          

          אודה מאוד מאוד לכל מי שיוכל לעזור אפי' במקצת.
          תודה רבה לכולם.

          פורסם במקור בפורום CODE613 ב25/12/2013 01:03 (+02:00)

          תגובה 1 תגובה אחרונה
          0
          • dovidD מחובר
            dovidD מחובר
            dovid ניהול
            כתב ב נערך לאחרונה על ידי
            #5

            לא הבנתי את הבעיה בקשר לשורה שהראית, זה אמור לעבוד.
            הקטע עם התבנית והבנאי, מאוד מעורפל.

            אבל אם כבר אראה לך איך עושים בצורה זאמלית את העסק.
            קודם הקטע עם ה+-:

            <DataGrid.RowHeaderTemplate >
                <DataTemplate>
                    <ToggleButton x:Name="btn" IsChecked="{Binding DetailsVisibility, Converter={StaticResource VisToBool}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}}" >
                        <ToggleButton.Style>
                            <Style TargetType="{x:Type ToggleButton}" >
                                <Setter Property="Content" Value="+" />
                                <Style.Triggers>
                                    <Trigger Property="IsChecked" Value="True">
                                        <Setter Property="Content" Value="-" />
                                    </Trigger>
                                </Style.Triggers>
                            </Style>
                        </ToggleButton.Style>
                    </ToggleButton>
                </DataTemplate>
            </DataGrid.RowHeaderTemplate>
            

            הקוד הזה עושה שימוש בקונוורטר. Converter זה משהו מאוד שימויש, במקרה של איגוד בין דברים "לא קשורים", כגון בין צבע למספר וכו'.
            הוא נעשה ע"י מופע של קלאס כלשהיא שמממשת את IValueConverter.
            הדרך ליצירת מופעים בxaml הוא פשוט להצהיר על קיומם, ובשביל זה גם צריך לייבא את הNamespace של הפרוייקט הנוכחי משהו כמו:

            <Window
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:WpfStyle""
                x:Class="MainWindow" Title="MainWindow" Height="350" Width="525">
                <Window.Resources>
                    <local:VisToBool x:Key="VisToBool"/>
                </Window.Resources>
            

            בשורה 4 מבוצע ייבוא ניימספייס לפרוייקט הנוכחי.
            בשורה 7 נוצר מופע של קונוורטר.

            הנה הקוד של הקלאס VisToBool:

            Class VisToBool
                Implements IValueConverter
                Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.Convert
                    Return CType(value, Visibility) = Visibility.Visible
                End Function
                Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
                    Return If(CBool(value) = True, Visibility.Visible, Visibility.Collapsed)
                End Function
            End Class
            

            פורסם במקור בפורום CODE613 ב25/12/2013 18:02 (+02:00)

            מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

            בכל נושא אפשר ליצור קשר dovid@tchumim.com

            תגובה 1 תגובה אחרונה
            0
            • dovidD מחובר
              dovidD מחובר
              dovid ניהול
              כתב ב נערך לאחרונה על ידי
              #6

              כעת לעניין טמפלטים משתנים כל שורה לפי X.
              בWPF יש DataTemplateSelector. שזה מחלקה שמחזירה DataTemplate לפי הטיפוס שהיא מקבלת.

              הדרכה קצרה:
              א. יוצרים טמפלטים לכל סיטואציה במקטע הResource של החלון (הסעיף הזה הוא לא מוכרח רק זה נח וככה עושים בד"כ).

              <DataTemplate x:Key="NormalTemplate">
                  <TextBlock Text="{Binding FirstName}" />
              </DataTemplate>
              
              <DataTemplate x:Key="VipTemplate">
                  <StackPanel>
                      <TextBlock Text="{Binding FirstName}" />
                      <TextBlock Text="{Binding LastName}" />
                  </StackPanel>
              </DataTemplate>
              

              ב. יוצרים קלאס שיורשת מDataTemplateSelector, ודורסים את מתודת SelectTemplate שם משתמשים עם הפרמטר item לבדוק מה להחזיר

              Class SelectTempletByRow
                  Inherits DataTemplateSelector
              
                  Shared win As MainWindow = Application.Current.MainWindow
              
                  Public Overrides Function SelectTemplate(item As Object, container As DependencyObject) As DataTemplate
                      If CType(item, Person).LastName = "דוד ל.ט." Then
                          Return win.FindResource("VipTemplate")
                      Else
                          Return win.FindResource("NormalTemplate")
                      End If
                  End Function
              End Class
              

              כעת מוסיפים למקטע הריסורס של החלון את הלאסס שעשינו:

              <local:SelectTempletByRow x:Key="Selector" />
              

              ומגדירים את המאפיין RowDetailsTemplateSelector של הDataGrid:

              RowDetailsTemplateSelector="{StaticResource Selector}"
              

              קצת מסובך אבל זה עקרונות מתקדמים ונחוצים בWPF, שווה!
              בהצלחה.

              פורסם במקור בפורום CODE613 ב25/12/2013 18:23 (+02:00)

              מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

              בכל נושא אפשר ליצור קשר dovid@tchumim.com

              תגובה 1 תגובה אחרונה
              1
              • רחמיםר מנותק
                רחמיםר מנותק
                רחמים מורחק
                כתב ב נערך לאחרונה על ידי
                #7

                תודה רבה זה מצויין,

                יש לי שתי שאלות לגבי הלחצן שבראש השורה:

                1. איך אפשר להגדיר שאם הלחצן בשורה האחרונה של הדטה-גריד שבכפתור יהיה כתוב '*' במקום '+' כיון שזו שורה שמיועדת ליצירת שורה חדשה ולא שייך לפתוח שם גליון משנה.

                2. איך אפשר לעשות שהלחצן עם ה '+' ישאר תמיד למעלה וכמו שכבר שאלתי באשכול אחר, ולא ירד תמיד לאמצע.

                לגבי טפלט שונה לכל שורה בשביל ה RowDetailsTemplate, זה הרבה יותר מורכב, כיון שב RowDetailsTemplate אני צריך לדחוף גליון נתונים שזה פקד שלם שמקבל בבנאי שלו פרמטר של "טבלה גנארית OF TRecord" וגם צריך להגדיר שהגליון הזה הוא משנה ולא ראשי ולפי איזה ID הוא יציג את השורות.
                אבל ישתבח שמו מצאתי פתרון בשיטה כזו:
                בתוך ה XAML הגדרתי שה RowDetailsTemplate יהיה רק גריד פשוט, ואז בארוע LoadingRowDetails יצרתי מופע של פקד חדש של הגליון נתונים עם כל מה שהוא צריך ואז הוספתי את הפקד לילדים של הגריד הנ''ל, למדתי את זה מכאן.

                פורסם במקור בפורום CODE613 ב25/12/2013 18:47 (+02:00)

                תגובה 1 תגובה אחרונה
                0
                • dovidD מחובר
                  dovidD מחובר
                  dovid ניהול
                  כתב ב נערך לאחרונה על ידי
                  #8

                  @רחמים

                  תודה רבה זה מצויין,

                  יש לי שתי שאלות לגבי הלחצן שבראש השורה:

                  1. איך אפשר להגדיר שאם הלחצן בשורה האחרונה של הדטה-גריד שבכפתור יהיה כתוב '*' במקום '+' כיון שזו שורה שמיועדת ליצירת שורה חדשה ולא שייך לפתוח שם גליון משנה.

                  2. איך אפשר לעשות שהלחצן עם ה '+' ישאר תמיד למעלה וכמו שכבר שאלתי באשכול אחר, ולא ירד תמיד לאמצע.

                  לגבי טפלט שונה לכל שורה בשביל ה RowDetailsTemplate, זה הרבה יותר מורכב, כיון שב RowDetailsTemplate אני צריך לדחוף גליון נתונים שזה פקד שלם שמקבל בבנאי שלו פרמטר של "טבלה גנארית OF TRecord" וגם צריך להגדיר שהגליון הזה הוא משנה ולא ראשי ולפי איזה ID הוא יציג את השורות.
                  אבל ישתבח שמו מצאתי פתרון בשיטה כזו:
                  בתוך ה XAML הגדרתי שה RowDetailsTemplate יהיה רק גריד פשוט, ואז בארוע LoadingRowDetails יצרתי מופע של פקד חדש של הגליון נתונים עם כל מה שהוא צריך ואז הוספתי את הפקד לילדים של הגריד הנ''ל, למדתי את זה מכאן.

                  בקשר לשאלות, עליך כמדומני לשנות את כותרת האשכול ל"איך פותרים את כל הבעיות שיש לי בWPF במהלך הימים הללו" :lol: , וברצינות: אין שום קשר בין השאלות.
                  בקשר ל"מורכבות העצומה" (מה שתיארת זה מקרה קלאסי של שתי תבניות לרשימה אחת) של הפירוט, אני שמח שהסתדרת :).

                  פורסם במקור בפורום CODE613 ב25/12/2013 19:01 (+02:00)

                  מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

                  בכל נושא אפשר ליצור קשר dovid@tchumim.com

                  תגובה 1 תגובה אחרונה
                  0
                  • רחמיםר מנותק
                    רחמיםר מנותק
                    רחמים מורחק
                    כתב ב נערך לאחרונה על ידי
                    #9

                    אולי באמת הגזמתי עם כ''כ הרבה שאלות...
                    אבל בסה''כ אני די חדש ב WPF, ותודה על כל העזרה העצומה והמיוחדת שאתה נותן לי ולכולם, יישר כח גדול!

                    פורסם במקור בפורום CODE613 ב25/12/2013 19:44 (+02:00)

                    תגובה 1 תגובה אחרונה
                    0
                    • dovidD מחובר
                      dovidD מחובר
                      dovid ניהול
                      כתב ב נערך לאחרונה על ידי
                      #10

                      תודה על המחמאות.
                      הבעיה זה לא כמות השאלות, שהפורום צמא לכאלו, אלא שצריך לייחד אשכול לכל נושא.

                      פורסם במקור בפורום CODE613 ב25/12/2013 19:50 (+02:00)

                      מנטור אישי למתכנתים (ולא רק) – להתקדם לשלב הבא!

                      בכל נושא אפשר ליצור קשר dovid@tchumim.com

                      תגובה 1 תגובה אחרונה
                      0

                      בא תתחבר לדף היומי!
                      • התחברות

                      • אין לך חשבון עדיין? הרשמה

                      • התחברו או הירשמו כדי לחפש.
                      • פוסט ראשון
                        פוסט אחרון
                      0
                      • דף הבית
                      • קטגוריות
                      • פוסטים אחרונים
                      • משתמשים
                      • חיפוש
                      • חוקי הפורום