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

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

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
  1. דף הבית
  2. תכנות
  3. קוד עבור ProgressDialog ב-C#

קוד עבור ProgressDialog ב-C#

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

    אמנם יש דברים כבר קיימים ויש גם כאלה שמשתמשים בAPI של ווינדוס אבל מטעמים שונים לא הייתי מרוצה מהם ולכן עשיתי את הקוד דלהלן:
    הקוד מציג את ההתקדמות על יד progressbar
    ועל ידי הצגת התקדמות מתוך ה-maximum כטקסט
    הקוד מציג גם את ההתקדמות באייקון בשורת המשימות
    הקוד מציג את ההתקדמות גם בפעולות async

    הקוד הוא בגדר סקיצה ואשמח מאוד לקבל משוב:

    using System;
    using System.Windows.Controls;
    using System.Windows;
    using System.Windows.Data;
    using System.Windows.Shell;
    
    namespace FullText.Controls
    {
        public static class ProgressDialog
        {
            public static IProgress<double> Start(string message, int maximum)
            {
                IProgress<double> reporter = null;
                Application.Current.Dispatcher.Invoke(() => {
    
                    TextBlock textBlock = new TextBlock { Text = message, TextWrapping = TextWrapping.WrapWithOverflow, Margin = new Thickness(5), };
                    ProgressBar progressBar = new ProgressBar { Maximum = maximum};
                    TextBlock percentageTextBlock = new TextBlock { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center , Margin = new Thickness(1) };
                    Binding binding = new Binding("Value") { Source = progressBar, StringFormat = $"{{0:0}} \\ {maximum}" };
                    percentageTextBlock.SetBinding(TextBlock.TextProperty, binding);
                    Grid grid = new Grid { Margin = new Thickness(5) };
                    grid.Children.Add(progressBar);
                    grid.Children.Add(percentageTextBlock);
                    StackPanel stackPanel = new StackPanel();
                    stackPanel.Children.Add(grid);
                    stackPanel.Children.Add(textBlock);
                    Window window = new Window
                    {
                        Content = stackPanel,
                        SizeToContent = SizeToContent.WidthAndHeight,
                        FlowDirection = FlowDirection.RightToLeft,
                        Owner = Application.Current.MainWindow,
                        ResizeMode = ResizeMode.CanMinimize
                    };
    
                    TaskbarItemInfo taskbarItemInfo = new TaskbarItemInfo();
                    //Application.Current.MainWindow.TaskbarItemInfo = taskbarItemInfo; 
                    window.TaskbarItemInfo = taskbarItemInfo;
                    taskbarItemInfo.ProgressState = TaskbarItemProgressState.Normal;
    
                    reporter = new Progress<double>(OnProgressChanged);
                    void OnProgressChanged(double incrementValue)
                    {
                        if (incrementValue == -1) { taskbarItemInfo.ProgressState = TaskbarItemProgressState.None; window.Close(); }
                        //else if (progressBar.Value >= progressBar.Maximum) { window.Close(); taskbarItemInfo.ProgressState = TaskbarItemProgressState.None; }
                        else 
                        {
                            progressBar.Value += incrementValue;
                            taskbarItemInfo.ProgressValue = (double)progressBar.Value / progressBar.Maximum; 
                        }
                    }
    
                    window.Show();
                });
    
                return reporter;
            }
        }
    }
    
    

    צורת שימוש
    התחלה

    var progressReporter = ProgressReporter.Start($"מאנדקס את: {directoryToIndex}", files.Count);
    

    התקדמות

     progressReporter.Report(1);
    

    סיום וסגירה

    progressReporter.Report(-1);
    

    גמ"ח מידע מחשבים ואופיס

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

      הערה חשובה:
      לאחר חקירת הנושא גיליתי שצריך לעבוד עם אחוזים ולא כמו שעשיתי
      עיין כאן להסבר מפורט
      https://brianlagunas.com/does-reporting-progress-with-task-run-freeze-your-wpf-ui/

      עריכה:
      בדיקות שעשיתי יוצא שבעל הכתבה איננו צודק לא היה שום שיפור באחוזים לעומת מה שאני עשיתי
      מה שכן מצאתי ששימוש ב- אפשרות של -Background ב-Dispathcer מועיל קימעא

      Application.Current.Dispatcher.BeginInvoke(new Action(() =>
      {
         }), DispatcherPriority.Background);
      

      גמ"ח מידע מחשבים ואופיס

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

        @pcinfogmach
        אף אחד לא ניסה לטעון שדיווח באחוזים שונה מכל ערך מספרי אחר.
        עיקר הנקודה שלו (וכנראה הטעות שלך) זו שורת הקוד הזאת:

         if (i % 1500 == 0)
        

        זה תו אחוז של תכנות שמשמעותו מודולו, כלומר שארית של המספר הנוכחי בחלוקה ל1500, שבעצם זה אומר שכל פעם שזה אפס עברו 1500 פעימות. אין לזה קשר למושג אחוזים במובן המקובל (למרות שבמקרה גמור בדוגמה שלו הוא בחר להציג אחוזים).
        הרעיון הוא לא לעדכן יותר מידי מהר את הUI, המאמר הזה מציג קוד שרירותי מידי וצריך לשנות אותו בהתאם למקרה ומה שצפוי להיות הזמן של כל פעימה. יותר גנרי ואלגנטי זה לעשות את זה עם טיימר של חצי שניה או 200 מילי שניות.

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

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

        pcinfogmachP תגובה 1 תגובה אחרונה
        2
        • pcinfogmachP מנותק
          pcinfogmachP מנותק
          pcinfogmach
          השיב לdovid ב נערך לאחרונה על ידי
          #4

          @dovid כתב בקוד עבור ProgressDialog ב-C#:

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

          הוא אשר דיברתי לא ראיתי שום הבדל בין שני שיטות מצג עידכון ה-UI
          הרעיון שלך עם טיימר לכאורה לא רלוונטי כאשר הזמן פעלה דינאמי כלומר כל פעימה זמנה משתנה תלוי בגודל קבצים וכיו"ב ואתה רוצה להציג את ההתקדמות בrealtime

          כל זה אני כותב כשאלה!?

          גמ"ח מידע מחשבים ואופיס

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

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

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

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

            pcinfogmachP תגובה 1 תגובה אחרונה
            1
            • dovidD מנותק
              dovidD מנותק
              dovid ניהול
              השיב לpcinfogmach ב נערך לאחרונה על ידי
              #6

              @pcinfogmach כתב בקוד עבור ProgressDialog ב-C#:

              הוא אשר דיברתי לא ראיתי שום הבדל בין שני שיטות מצג עידכון ה-UI

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

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

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

              תגובה 1 תגובה אחרונה
              2
              • pcinfogmachP מנותק
                pcinfogmachP מנותק
                pcinfogmach
                השיב לdovid ב נערך לאחרונה על ידי pcinfogmach
                #7

                @dovid כתב בקוד עבור ProgressDialog ב-C#:

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

                עשיתי קוד בדיוק כמו שהוא עשה ולא ראיתי שום הבדל בשני השיטות בשניהם זה לא נתקע
                אצלי זה נתקע בגלל שהיה הרבה קראות IO כך שלא היה נפ"מ באיזו תכיפות מעדכנים את ההתקדמות כי בזמן העדכון לרוב התוכנה היתה עסוקה בין כך. במקרה הזה מה שכתבתי למעלה להשתמש ב-dispatcher עזר לזה.

                גמ"ח מידע מחשבים ואופיס

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

                  @pcinfogmach אוי... אם טוב לך אני לא אטריד אותך.

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

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

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

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

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

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