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

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

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
pcinfogmachP

pcinfogmach

@pcinfogmach
אודות
פוסטים
690
נושאים
185
קבוצות
0
עוקבים
3
עוקב אחרי
1

פוסטים

פוסטים אחרונים הגבוה ביותר שנוי במחלוקת

  • מבנה נתונים גלובלי עבור Checked TreeView ב-Wpf
    pcinfogmachP pcinfogmach

    7565919b-5ed3-46b3-a7ae-98317cc9b0df-image.png

    כידוע, הדרך הטובה ביותר להתנהל עם TreeView ב-WPF היא עם מבנה נתונים הררכי, ו-HierarchicalDataTemplate ב-WPF נבנה במיוחד למטרה זו.
    אחרי שמצאתי את עצמי בפעם השלישית בונה מבנה נתונים עבור Checked TreeView (ראה תמונה), החלטתי לשבת כמה דקות ולבנות משהו יותר גלובלי שיאפשר לי להשתמש בו גם בעתיד. הרעיון הוא לייצר מחלקה בסיסית המכילה את כל מה שדרוש עבור מטרה זו, כך שאוכל לרשת אותה ולהשתמש בה עבור כל מבנה נתונים הררכי באופן כללי עם הדרישה הזו של Checked TreeView.

    שימו לב! אני הגדרתי את ה-Default של ה-IsChecked כ-false ייתכן ותרצו לשנות את זה ל-true תלוי באמפלמנטציה שלכם.

    אם לא הבנתם את הנושא דיו והוא מעניין אתכם? אנא קיראו כתבה זו כהקדמה:
    https://www.codeproject.com/Articles/26288/Simplifying-the-WPF-TreeView-by-Using-the-ViewMode

    להלן הקוד:

    ///sample usage
    //public class MyCheckedItem : TreeItemBase<MyCheckedItem>
    //{
    //    // Custom properties if needed
    //}
    
    using System.Collections.Generic;
    using System.Linq;
    
    namespace WpfLib.ViewModels
    {
        public class CheckedTreeItemBase<T> : TreeItemBase<T> where T : CheckedTreeItemBase<T>
        {
            bool? _isChecked = false;
            public bool? IsChecked { get => _isChecked; set => SetCheckedValue(value, true); }
    
            public void SetCheckedValue(bool? isChecked, bool updateChildren)
            {
                if (SetProperty(ref _isChecked, isChecked, nameof(IsChecked)))
                {
                    if (updateChildren && Items != null)
                    {
                        foreach (var child in Items)
                        {
                            if (child.IsChecked != isChecked)
                                child.IsChecked = isChecked == true;
                        }
                    }
    
                    if (Parent != null)
                    {
                        var siblings = Parent.Items;
                        var parentCheckedValue = siblings.All(c => c.IsChecked == true) ? true :
                                                 siblings.All(c => c.IsChecked == false) ? (bool?)false : null;
                        Parent.SetCheckedValue(parentCheckedValue, false);
                    }
                }
            }
    
            public IEnumerable<T> EnumerateCheckedItems()
            {
                if (Items != null)
                {
                    foreach (var child in Items)
                    {
                        if (child.IsChecked == true)
                            yield return child;
    
                        foreach (var item in child.EnumerateCheckedItems())
                            yield return item;
                    }
                }
            }
        }
    }
    

    המודל יורש ממודל treeitembase שמשמש כבסיס לכל מודל היררכי בעץ נתונים

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Text.Json.Serialization;
    
    namespace WpfLib.ViewModels
    {
        public class TreeItemBase<T> : ViewModelBase where T : TreeItemBase<T>
        {
            string _name;
            ObservableCollection<T> _items = new ObservableCollection<T>();
    
            [JsonIgnore] public T Parent { get; set; }
            public virtual string Name { get => _name; set => SetProperty(ref _name, value); }
            public ObservableCollection<T> Items { get => _items; set => SetProperty(ref _items, value); }
    
            public override string ToString() => Name;
    
            public void AddChild(T item)
            {
                if (Items == null)
                    Items = new ObservableCollection<T>();
                Items.Add(item);
                item.Parent = (T)this;
            }
    
            public IEnumerable<T> EnumerateItems()
            {
                if (_items == null) yield break;
    
                foreach (var item in _items)
                {
                    yield return item;
                    foreach (var child in item.EnumerateItems())
                        yield return child;
                }
            }
        }
    
    }
    
    

    המודל יורש מודל אחר שימושי בשם ViewModelBase המהווה בסיס טוב עבור כל viewModle ב-Wpf

    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    
    namespace MyModels
    {
        public class ViewModelBase : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected virtual void OnPropertyChanged(string propertyName)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
    
            protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
            {
                if (EqualityComparer<T>.Default.Equals(field, value)) return false;
                field = value;
                OnPropertyChanged(propertyName);
                return true;
            }
        }
    
    }
    
    

  • עזרה בביטוי רגולארי
    pcinfogmachP pcinfogmach

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

    אם נתעלם לרגע מהנקודה ומה-"|", נוכל להשתמש בשילוב של רג'קס וקוד רקורסיבי עם מבנה נתונים פשוט (@dovid רמז לזה כבר).
    אבל חשוב לציין שזה בהנחה שהטקסט לא מכיל שגיאות או אי-עקביות – אחרת זה כאב ראש * 20.
    להלן דוגמא ב-C# שהזנתי ל-LinqPad, הקוד הינו סקיצה בעלמא תוכל לשפר אותו כיד ה' הטובה עליך:

    void Main()
    {
        string content = "{{some content{{some more content{{some more content{{some more content}}}}}}}}";
            var root = new NestedContent(content, null);
            root.Dump(); // Dump the root object to view its structure
    }
    
    class NestedContent
    {
        public string Content { get; set; }
        public NestedContent Child { get; set; }
    
        public NestedContent(string content, NestedContent parent)
        {
            // Trim only the outermost braces (single pair at start and end)
            if (content.StartsWith("{{") && content.EndsWith("}}"))
            {
                content = content.Substring(2, content.Length - 4);
            }
    
            var match = Regex.Match(content, @"\{\{.*\}\}");
            if (match.Success)
            {
                string nestedContent = match.Value;
                this.Content = content.Replace(nestedContent, ""); // Replace inner braces content
                Child = new NestedContent(nestedContent, this); // Recursive call for nested content
            }
            else
            {
                this.Content = content; // Set content when no more nested structures
            }
        }
    }
    
    

    והתוצאה:

    d7b843dd-ffba-4875-bdb5-2e95805263aa-image.png


  • עזרה בביטוי רגולארי
    pcinfogmachP pcinfogmach

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

    אישית לא הייתי שואל ככה אלא איך לפתור את הבעיה והאם רגקס הוא כיוון טוב.


  • Debugging על ViewModel ב-WPF
    pcinfogmachP pcinfogmach

    @yossiz כתב בDebugging על ViewModel ב-WPF:

    אגב, אני לא מפתח WPF אבל יצרתי פרוייקט דמו כדי לבדוק את הנושא
    הוספתי לפרוייקט שלי UserControl ובתוך הconstructor זרקתי שגיאה

    אכן במקרה כזה אין לי בעיות הבעיות מתחילות כאשר אני משתמש במבנה MVVM ויש בעיה במודל או ב-ViewModel (שם עיקר הכוח של wpf בא לידי ביטוי). נכון אפשר להסתכל על פרטי השגיאה אבל זה די מתסכל לא להגיע ישר לבעיה ולתקן כמו שאני רגיל.
    מה שכתבת בהחלט עזר לי להבין יותר. התיעוד בכל הנושא הזה מאוד לא ברור לי. ובפרט מה בדיוק עושה מה ש@Mordechai-0 אמר Enable Just my code. הנסיון שלי הוא ש-visual studio הוא תוכנה מורכבת וכשמתחילים לשנות את ההגדרות אם לא באמת מבינים מה עושים אזי עדיף לא לשנות.


  • Debugging על ViewModel ב-WPF
    pcinfogmachP pcinfogmach

    @Mordechai-0
    אתה יכול להרחיב קצת על מה האפשרות הזו עושה (ובפרט למה זה לא ה-default?)
    תודה


  • Debugging על ViewModel ב-WPF
    pcinfogmachP pcinfogmach

    כאשר יש בעיה ב-ViewModel אצלי במקום לעצור על נקודת הבעיה כמו שקורה כרגיל ב-C# הוא עוצר על נקודה זו (שבתמונה דלהלן) יש למישהו עצה?

    6f887d7e-8fbb-4c77-84b2-c4d2c5a36fd5-image.png


  • API לקבלת רשימת דפים וסימנים בספרי היסוד התורניים
    pcinfogmachP pcinfogmach

    @NH-LOCAL
    כדי להתגבר על חוסר העקביות ברמות הכותרות, אפשר להשתמש במבנה היררכי, כמו Stack, כדי לעקוב אחר ה-parent האחרון. כך ניתן לתקן את רמת הכותרת בהתאם להקשר ולהבטיח זיהוי נכון של המספרים והכותרות.


  • TextBoxFocusBehavior - לשיפור חוויית המשתמש ב-WPF
    pcinfogmachP pcinfogmach

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


  • TextBoxFocusBehavior - לשיפור חוויית המשתמש ב-WPF
    pcinfogmachP pcinfogmach

    כאשר עובדים עם TextBox ב-WPF, לפעמים נרצה לשפר את חוויית המשתמש על ידי ביצוע פעולות אוטומטיות, כמו בחירת כל הטקסט כאשר הרכיב מקבל פוקוס או קביעה אוטומטית של פוקוס על TextBox בעת הטעינה.

    אשמח לקבל הערות והארות.

    מצו"ב הקוד:

    public class TextBoxFocusBehavior
    {
        public static bool GetSelectAll(FrameworkElement frameworkElement)
        {
            return (bool)frameworkElement.GetValue(SelectAllProperty);
        }
    
        public static void SetSelectAll(FrameworkElement frameworkElement, bool value)
        {
            frameworkElement.SetValue(SelectAllProperty, value);
        }
    
        public static bool GetCaptureFocus(FrameworkElement frameworkElement)
        {
            return (bool)frameworkElement.GetValue(CaptureFocusProperty);
        }
    
        public static void SetCaptureFocus(FrameworkElement frameworkElement, bool value)
        {
            frameworkElement.SetValue(CaptureFocusProperty, value);
        }
    
        public static readonly DependencyProperty CaptureFocusProperty =
            DependencyProperty.RegisterAttached("CaptureFocus",
                typeof(bool), typeof(TextBoxFocusBehavior),
                new FrameworkPropertyMetadata(false, OnCaptureFocusChanged));
    
        public static readonly DependencyProperty SelectAllProperty =
                 DependencyProperty.RegisterAttached("SelectAll",
                    typeof(bool), typeof(TextBoxFocusBehavior),
                    new FrameworkPropertyMetadata(false, OnSelectAllChanged));
    
        private static void OnSelectAllChanged
                   (DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var frameworkElement = d as FrameworkElement;
            if (frameworkElement == null) return;
    
            if (e.NewValue is bool == false) return;
    
            if ((bool)e.NewValue)
            {
                frameworkElement.GotFocus += SelectAll;
                frameworkElement.PreviewMouseDown += IgnoreMouseButton;
            }
            else
            {
                frameworkElement.GotFocus -= SelectAll;
                frameworkElement.PreviewMouseDown -= IgnoreMouseButton;
            }
        }
    
        private static void OnCaptureFocusChanged
                  (DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var frameworkElement = d as FrameworkElement;
            if (frameworkElement == null) return;
    
            if (e.NewValue is bool == false) return;
    
            if ((bool)e.NewValue)
            {
                frameworkElement.Loaded += FrameworkElement_Loaded;
            }
            else
            {
                frameworkElement.Loaded -= FrameworkElement_Loaded;
            }
        }
    
        private static void FrameworkElement_Loaded(object sender, RoutedEventArgs e)
        {
            var frameworkElement = e.OriginalSource as FrameworkElement;
            frameworkElement.Focus();
        }
    
        private static void SelectAll(object sender, RoutedEventArgs e)
        {
            var frameworkElement = e.OriginalSource as FrameworkElement;
            if (frameworkElement is TextBox)
                ((TextBoxBase)frameworkElement).SelectAll();
            else if (frameworkElement is PasswordBox)
                ((PasswordBox)frameworkElement).SelectAll();
        }
    
        private static void IgnoreMouseButton
                (object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            var frameworkElement = sender as FrameworkElement;
            if (frameworkElement == null || frameworkElement.IsKeyboardFocusWithin) return;
            e.Handled = true;
            frameworkElement.Focus();
        }
    }
    

    המחלקה TextBoxFocusBehavior מספקת שתי יכולות:

    Select All: בחירת כל הטקסט כאשר הרכיב מקבל פוקוס.
    Capture Focus: קביעה כי רכיב מסוים יקבל פוקוס אוטומטית בעת טעינת החלון.
    

    דוגמאות שימוש:

    <TextBox Text="Hello, World!" 
             local:TextBoxFocusBehavior.SelectAll="True" 
             local:TextBoxFocusBehavior.CaptureFocus="True" />
    

  • מדריך: איך לייצר לוקליזציה ב-wpf בצורה פשוטה וקלילה
    pcinfogmachP pcinfogmach

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


  • התייעצות בתכנון מסד נתונים עבור מאגר תורני
    pcinfogmachP pcinfogmach

    @yossiz
    אוקיי הבנתי הטענה היא שמספיק למפות את הקובץ לא צריך לשמור אותו כלל במסד - יפה!
    כמובן שיש משהו שמרוויחים חינם במסד והוא היכולת חיפוש בתוכן.


  • התייעצות בתכנון מסד נתונים עבור מאגר תורני
    pcinfogmachP pcinfogmach

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


  • התייעצות בתכנון מסד נתונים עבור מאגר תורני
    pcinfogmachP pcinfogmach

    למרות המבנה המבטיח אני עדיין תוהה לעצמי מה הדרך הכי טובה למפות מיקום מדוייק בתוך המבנה ההיררכי. למשל אם ארצה לחפש האם כתובת מדוייקת קיימת (כגון: בראשית, א, קלט - לא קיים. אבל בראשית, א, יד - קיים).
    האם להוסיף עוד טור שמתאר את הכתובת המלאה או לחפש את זה בצורה היררכית על ידי שיוכים של parent - child


  • התייעצות בתכנון מסד נתונים עבור מאגר תורני
    pcinfogmachP pcinfogmach

    @pcinfogmach
    אוקיי מצאתי לכאורה את הדרך האופטימלית (כלומר מודל שימושי כאשר יש צורך לשאול שאילתות על בסיסי נתונים המכילים מבנים מסודרים בצורה היררכית). בכתבה זו (החלק השני):
    https://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
    הרעיון נקרא :

    The Nested Set Model


    המודל ההיררכי של ה-Nested Set מבוסס על שימוש בטווחי מספרים לתיאור מבנה היררכי בצורה שטוחה המתאימה למסד sql. כל אלמנט במבנה מוגדר על ידי שני מספרים: ערך "שמאל" (Left) וערך "ימין" (Right), המייצגים את גבולות הטווח שלו בתוך המבנה.

    לדוגמה, נניח שיש לנו את המבנה הבא:

    ספר: כותרת הספר
        פרק 1
            פסוק 1
            פסוק 2
        פרק 2
            פסוק 1
    

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

    הספר כולו: טווח 1-12
    פרק 1: טווח 2-7
        פסוק 1: טווח 3-4
        פסוק 2: טווח 5-6
    פרק 2: טווח 8-11
        פסוק 1: טווח 9-10
    

    להלן הייצוג הטבלאי של המסד:
    64f3a51c-a3f5-4748-8684-66eca37c94a4-image.png

    העקרונות המרכזיים במודל זה:

    • טווח של כל רכיב כולל את הטווחים של כל תתי-הרכיבים שבתוכו.

    • וממילא טווחים שאינם חופפים מצביעים על כך שהרכיבים אינם קשורים ישירות במבנה.

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

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

    תמונות להמחשה מתוך הכתבה הנ"ל (מקווה שלא תסקלו אותי על זה שכתוב פה טלויזיה עשיתי העתק הדבק איתכם הסליחה).
    f1e1d87f-75fa-456e-9c10-f33756d52f4e-nested_numbered.png
    94326caf-f007-4966-a04b-95902e244646-numbered_tree.png


  • התייעצות בתכנון מסד נתונים עבור מאגר תורני
    pcinfogmachP pcinfogmach

    התייעצות בבניית מסד נתונים עבור מאגר תורני
    לבינתיים זהו המבנה שחשבתי עליו ביקשתי מ-gpt שיצייר את זה יפה
    אשמח לקבל משוב ועצות לשיפור.
    הקושי שלי בעיקר הוא מה העצה הכי טובה בשביל מסד שבנוי בצורה היררכית.

    beda0c1a-cee2-4f79-9a7f-0840efeb4678-image.png


  • מדריך: איך לייצר לוקליזציה ב-wpf בצורה פשוטה וקלילה
    pcinfogmachP pcinfogmach

    פתרון פשוט וקליל ללוקליזציה באפליקציות WPF

    (הקוד נמצא בסוף הכתבה)

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

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

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

    השלבים לבניית הפתרון:
    א. שימוש בקובץ JSON
    קובץ JSON מאפשר לנו לנהל ולערוך את כל המחרוזות של האפליקציה בצורה מסודרת ונוחה. המפתח (Key) מייצג את שם הפריט, והערך (Value) מייצג את המחרוזת המתורגמת.
    עבור כל שפה נייצר קובץ נפרד עם הקידומת של השפה בתוך התיקייה הייעודית (בקוד להלן אני בחרתי "Asstes//Locale").
    הקידומת תהיה בת שני אותיות בלבד ובאותיות קטנות למשל "he" או "en".
    שימו לב! בקוד שכתבתי שפת המערכת מזוהה באופן אוטומטי ייתכן וגישה זו איננה מתאימה לכם.
    ב. שימוש במבנה Dictionary סטטי
    אנו נטען את תוכן ה-JSON לקובץ זיכרון באמצעות מילון (Dictionary) סטטי, שיהיה זמין לכל רכיבי האפליקציה.
    ג. שימוש ב-Markup Extension
    ניצור הרחבה מותאמת אישית (Markup Extension) שתאפשר לנו לגשת למחרוזות מתוך ה-JSON ישירות מתוך ה-XAML. (כמו"כ נוכל לצפות בתוצאות בתצוגה המקדימה של עורך ה-Xaml).

    דגשים חשובים לניהול הפתרון:

    • שמות זהים לשמות הפקדים: הקפידו על כך ששמות המפתחות ב-JSON יהיו זהים לשמות הפקדים שאותם הם מתארים. כך, תוכלו לשמור על עקביות ולמנוע טעויות.

    • מבנה עם תיאור ברור: הוסיפו תיאור לכל מפתח בקובץ ה-JSON, כך שיהיה קל להבין מה הוא מייצג. מומלץ לצורך זה להשתמש בתיאורים המובנים של WPF. לדוגמה:

    {
        "Tooltip.MinimizeButton": "Minimize",
        "Tooltip.CloseButton": "Close",
        "Title.MainWindowTitle": "My Application"
    }
    

    העיקרון הזה יקל עליכם גם בכתיבת ה-JSON וגם בייחוס המפתחות ישירות מתוך ה-XAML.
    סדר אלפא ביתי של המפתחות ייקל על עריכת שינויים והתמצאות כללית ב-JSON.

    להלן הקוד:

    using System.Globalization;
    using System.IO;
    using System.Text.Json;
    using System.Text.RegularExpressions;
    using System.Windows;
    using System.Windows.Markup;
    
    namespace Assets.Locale
    {
     public class LocalizedStringExtension : MarkupExtension
     {
         public string Key { get; set; }
    
         public LocalizedStringExtension() { }
         public LocalizedStringExtension(string key) { Key = key; }
    
         public override object ProvideValue(IServiceProvider serviceProvider)
         {
             if (string.IsNullOrEmpty(Key)) return "[Missing Key]"; 
             else  return LocaleHelper.LocaleDictionary.TryGetValue(Key, out var value) ? value : $"[{Key}]";
         }
     }
    
        public static class LocaleHelper
        {
            private static readonly string LocaleDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Assets", "Locale");
            private static string LocalePath =>
                Path.Combine(LocaleDir, $"{CultureInfo.CurrentCulture.TwoLetterISOLanguageName}.json") is string path && File.Exists(path)
                    ? path
                    : Path.Combine(LocaleDir, "en.json");
    
            private static Dictionary<string, string>? _localeDictionary;
            public static Dictionary<string, string> LocaleDictionary => _localeDictionary ??= LoadLocaleDictionary();
    
            private static Dictionary<string, string> LoadLocaleDictionary()
            {
                if (!File.Exists(LocalePath))
                    return new Dictionary<string, string>();
    
                try
                {
                    string json = File.ReadAllText(LocalePath);
                    return JsonSerializer.Deserialize<Dictionary<string, string>>(json) ?? new Dictionary<string, string>();
                }
                catch
                {
                    // Return an empty dictionary if reading or deserialization fails
                    return new Dictionary<string, string>();
                }
            }
        }
    }
    
    

    ובתוך ה-xaml יש להוסיף

     xmlns:locale="clr-namespace:Assets.Locale"
    

    ואז תוכלו למשל לעשות כך

      <Button x:Name="MinimizeButton"
      ToolTip="{locale:LocalizedString Key='Tooltip.MinimizeButton'}">
    

  • תורת אמת בוורד - עכשיו בvsto
    pcinfogmachP pcinfogmach

    @שימילה
    תשלח לי מייל אני קצת עמוס מקווה שאתפנה לזה
    לבינתיים תשאל כאן

    אולי תקבל תשובה יותר טובה


  • תורת אמת בוורד - עכשיו בvsto
    pcinfogmachP pcinfogmach

    @שימילה
    ניסית להתקין על ידי קובץ הVSTO או על ידי-SETUP
    האם הסרת חסימה אינטרנטית מהקובץ
    האם סגרת את וורד לפני ההתקנה

    כמו"כ מומלץ להוריד את הגירסה המעודכנת
    https://mitmachim.top/topic/68192/להורדה-תורת-אמת-בוורד-גרסה-3?_=1732199524654

  • 1 / 1
  • התחברות

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

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