שאלה: איך עושים בתוסף vsto לוורד שtaskpane יישאר תמיד בחלונית האקטיבית
-
@dovid כתב בשאלה: איך עושים בתוסף vsto לוורד שtaskpane יישאר תמיד בחלונית האקטיבית:
האזנה לסגירה אתה יכול לעשות עם האירוע taskPane.VisibleChanged שמה בתוכו אתה יכול לבדוק את taskPane.Visible.
מה עם הבעיות הנ"ל?
https://tchumim.com/post/157637 -
אני לא לגמרי מבין את הבעיה, ובאיזה שלב גם קשה לעקוב אחרי הכל, אבל בוא ננסה לפרק את הבעיה לגורמים
א'. יש לנו אוסף של חלוניות צד, ויש לנו בעיה שאנחנו רוצים שיופיע בכל מסמך שנפתח, מה שלא מובנה בוורד.
ב'. במידה והצלחנו נהיה לנו בעיה אחרת שאנחנו רוצים שלפעמים זה יופיע רק בחלק מהמסמכים [בהנחה והבנתי נכון]
הבעיה הראשונה כבר הרב דוד כתב פתרון ואין צורך להגיב עליה.
לבעיה השנייה לכאורה הפתרון הוא ליצור מילון סטטי, [או LIST של מחלקה התוצאה זהה] והוסיף לפונקציה שאיתה המתכנת קורא לתיבות צד, שתי דברים
א'. להוסיף שכל פעם שפותחים את החלונית, החלונית תירשם באוסף כל שהוא.
ב'. כשפתוחים חלונית ניתן בעת יצירת האוביקט לקרוא לאירוע סגירה, שמודיע לי כשהחלונית נסגרה
ג'. יש מובנה בוורד רשימה של כל המסמכים הפתוחים.בעצם כעת יש לנו שלוש רשימות, חלונות צד [הפתוחים] מסמכים, והשלישי ניצור המסמכים שבהם אנחנו לא רוצים שיהיה את החלונות צד.
בקוד זה בעצם מחלקה כזו [בצורה גסה]public class חלונותצד { public object החלון { get;set; } public Dictionary<string, bool> המסמכים { get; set; } }
במילון אנחנו מאחסנים רשימה של המסמכים שנפתחים, בעצם באירוע של פתיחת מסמך הוא נוסף למילון או לכל מילון שקיים [זה אומר כל חלונית צד שפתוחה וקיימת באוסף]
במידה והמשתמש סוגר את החלונית באותו מסמך, המסמך מקבל במילון את הערך שקר, ככה שמתי שהוא חוזר לתצוגה [אירוע פוקוס או אירוע מסמך הופעל וכהנה וכהנה] יש בדיקה בקוד, אם הוא סימן את החלונית צד כשקר היא לא עולה, ואם לא היא עולה.עד כאן בצורה גסה, צר לי על ההסבר הארוך שגם קצת מורכב, זה הסגנון שאני כותב בו קוד.
הרבה הצלחה בהכל, ומקווה שהתוסף הזה יביא דברים טובים -
@YAKOV2024 כתב בשאלה: איך עושים בתוסף vsto לוורד שtaskpane יישאר תמיד בחלונית האקטיבית:
אני לא לגמרי מבין את הבעיה, ובאיזה שלב גם קשה לעקוב אחרי הכל, אבל בוא ננסה לפרק את הבעיה לגורמים
א'. יש לנו אוסף של חלוניות צד, ויש לנו בעיה שאנחנו רוצים שיופיע בכל מסמך שנפתח, מה שלא מובנה בוורד.
ב'. במידה והצלחנו נהיה לנו בעיה אחרת שאנחנו רוצים שלפעמים זה יופיע רק בחלק מהמסמכים [בהנחה והבנתי נכון]א. יש רק אחת, וזה אכן סודר שתמיד יופיע בפעיל
ב. להבנתי לא הייתה כזו דרישה, אלא שלחצן ההסתרה המובנה יחול גם במעבר למסמך אחר (כלומר שלא יופעל הקוד שכתבנו שכן תופיע שמה חלונית). הבעיה היא שאין שום אירוע ייעודי ללחצן הזה, ואין דרך לדעת שהוא נלחץ כלל. -
@dovid
עוד לא ישבתי על זה לעומק אבל כמדומני שהתגובה שלך היא לשיטתך.
כלומר @YAKOV2024 מציע שיטת עבודה אחרת לגמרי ממה שגיבשנו עד כה -
אני רוצה לסכם היכן אנחנו אוחזים:
בעצם יש לנו קוד נפלא של @dovid שמעביר את החלונית צד מממסמך למסמך בצורה נקייה וטובה.
אפשר להגדיר bool שיקבל ערך שקר בעת לחיצה על לחצן הסגירה של חלונית הצד על ידי taskPane.VisibleChanged += TaskPane_VisibleChanged;
ומאידך יקבל ערך אמת על ידי לחיצה על כפתור הפתיחה של החלונית צד.
אפשר גם להוסיף עוד bool ב settings של התוכנה שיתן למשתמש אפשרות לבחור אם החלונית צד תקפוץ ממסמך למסמך או לא.
ויש לנו את ההצעה של @YAKOV2024 שטוען שאולי אפשר להשתמש עם רשימה שרושמת את המסמכים הפתוחים ובכך נוכל להגדיר שרק במסמך המסויים בו נסגר החלונית צד שמה לא יצוץ שוב אבל יישאר בכל שאר המסמכים. -
@pcinfogmach כתב בשאלה: איך עושים בתוסף vsto לוורד שtaskpane יישאר תמיד בחלונית האקטיבית:
שרק במסמך המסויים בו נסגר החלונית
זהו, שאין דרך לדעת בכלל שנסגר החלונית במסמך מסויים.
מעקב אחרי VisibleChanged לא אומר כלום כי אפילו מעבר ממסמך למסמך מעורר אותו.
זו נקודת הבעיה היחידה שלנו. -
@dovid
תתקן אותי אם אני טועה
לכאורה אפשר לעשות פשוט שכאשר מסמך מסויים הוא נהיה אקטיבי אז זה מעורר משתנה ואז כאשר יש את הטריגר של visiblechanged אז הוא רושם מהו המסמך ומה היה המצב של visiblechanged (כל זה הבנתי מדבריו של @YAKOV2024 ) -
@dovid כתב בשאלה: איך עושים בתוסף vsto לוורד שtaskpane יישאר תמיד בחלונית האקטיבית:
אמת, אבל הVisibleChanged מתעורר על שטויות, למשל פתיחת כרטסת הבית הופכת אותו ללא נראה.
??? לא קרה אצלי
הנה הקוד שלי - לא כולל ההצעה של @YAKOV2024 לבינתיים
(הקוד הוא עבור xml ribbonusing Microsoft.Office.Interop.Word; using Microsoft.Office.Tools.Ribbon; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using Word = Microsoft.Office.Interop.Word; using Office = Microsoft.Office.Core; using Microsoft.Office.Core; using System.Windows.Forms; namespace ToratEmetInWord_2._0 { [ComVisible(true)] public class Ribbon : Office.IRibbonExtensibility { private Office.IRibbonUI ribbon; Microsoft.Office.Tools.CustomTaskPane taskPane; private Word.Document lastDoc; private UserControlContainer container; private UserControl1 ToratEmetTaskPane = new UserControl1(); private bool windowSnap; public Ribbon() { } #region IRibbonExtensibility Members public string GetCustomUI(string ribbonID) { return GetResourceText("ToratEmetInWord_2._0.Ribbon.xml"); } #endregion #region Ribbon Callbacks //Create callback methods here. For more information about adding callback methods, visit https://go.microsoft.com/fwlink/?LinkID=271226 public void Ribbon_Load(Office.IRibbonUI ribbonUI) { this.ribbon = ribbonUI; Globals.ThisAddIn.Application.DocumentChange += Application_DocumentChange; } private void Application_DocumentChange() { if (Properties.Settings.Default.snapWithWindow == true && windowSnap ==true) { loadPanel(); } } public System.Drawing.Image GetImage(Office.IRibbonControl control) { System.Drawing.Bitmap image = Properties.Resources.תורת_אמת2; return image; } public void toratEmetButton_Click(IRibbonControl control) { windowSnap = true; loadPanel(); } private void loadPanel() { if (Globals.ThisAddIn.Application.Documents.Count == 0 || lastDoc == Globals.ThisAddIn.Application.ActiveDocument) return; lastDoc = Globals.ThisAddIn.Application.ActiveDocument; if (taskPane != null) { container.Controls.Remove(ToratEmetTaskPane); Globals.ThisAddIn.CustomTaskPanes.Remove(taskPane); } container = new UserControlContainer(ToratEmetTaskPane); taskPane = Globals.ThisAddIn.CustomTaskPanes.Add(container, "תורת אמת"); taskPane.Visible = true; taskPane.Width = 450; taskPane.VisibleChanged += TaskPane_VisibleChanged; } private void TaskPane_VisibleChanged(object sender, EventArgs e) { if (!taskPane.Visible) { windowSnap = false; } } #endregion #region Helpers private static string GetResourceText(string resourceName) { Assembly asm = Assembly.GetExecutingAssembly(); string[] resourceNames = asm.GetManifestResourceNames(); for (int i = 0; i < resourceNames.Length; ++i) { if (string.Compare(resourceName, resourceNames[i], StringComparison.OrdinalIgnoreCase) == 0) { using (StreamReader resourceReader = new StreamReader(asm.GetManifestResourceStream(resourceNames[i]))) { if (resourceReader != null) { return resourceReader.ReadToEnd(); } } } } return null; } #endregion } public class UserControlContainer : UserControl { public UserControlContainer(UserControl1 control) { Controls.Add(control); control.Dock = DockStyle.Fill; } } }
-
@dovid כתב בשאלה: איך עושים בתוסף vsto לוורד שtaskpane יישאר תמיד בחלונית האקטיבית:
סליחה, כרטסת "קובץ" שמכסה את כל הדף.
שים נקודת עצירה בשורה 92, ולחץ על "קובץ".צודק! אבל הפתרון הוא פשוט על ידי הגדרת תנאי כפול.
if (!taskPane.Visible) { windowSnap = false; } else { windowSnap = true; }
-
@pcinfogmach כתב בשאלה: איך עושים בתוסף vsto לוורד שtaskpane יישאר תמיד בחלונית האקטיבית:
ב. הוא עוזר בגלל שברגע שאתה סוגר את "קובץ" ממילא שוב יש טריגר של visiblechanged והפעם הוא נהיה visible
בתנאי שאתה לא לוחץ על מסמך חדש, שאז אתה לא חוזר ואז זה לא נהיה visible...
-
@dovid כתב בשאלה: איך עושים בתוסף vsto לוורד שtaskpane יישאר תמיד בחלונית האקטיבית:
בתנאי שאתה לא לוחץ על מסמך חדש, שאז אתה לא חוזר ואז זה לא נהיה visible...
המעניין הוא שזה רק קורה כשפותחים מסמך חדש לגמרי אבל לא כאשר פותחים מסמך שמור.
למעשה אולי אפשר לעשות שהוא יבדוק מה המצב של החלונית צד במסמך הקודם. -
@dovid
מצאתי פיתרון!Globals.ThisAddIn.Application.WindowDeactivate += Application_WindowDeactivate; private void Application_WindowDeactivate(Document Doc, Window Wn) { if (taskPane != null && taskPane.Visible) { windowSnap = true; } }
זה קולט את המצב של החלונית צד בעת פתיחת מסמך חדש.
אבל מצאתי גם בעיה אחרת
כאשר סוגרים מסמך ללא שמירה החלונית נעלמת עד המעבר הבא בין מסמכים.
לבינתיים רק מצאתי לזה אילתור מצחיק ובלתי מומלץ מסיבות פשוטותGlobals.ThisAddIn.Application.DocumentBeforeClose += Application_DocumentBeforeClose; private void Application_DocumentBeforeClose(Document Doc, ref bool Cancel) { Globals.ThisAddIn.Application.ActiveWindow.WindowState = WdWindowState.wdWindowStateMinimize; }
מה שיוצר מצב שהחלונית הנסגרת איננה החלונית האקטיבית
-
סליחה שאני מגיב על שרשור ישן אבל נוצרה לי בעיה עם הקוד
עד היום הכל עבד חלק פתאום התחיל להיות אצלי וגם אצל חברים שלי בעיה במעבר בין חלונות שזה ממש לא עושה את זה חלק (שהייה של כמה רגעים טובים ולפעמים גם תוקע את וורד)זה קורה רק כאשר יש פקד webbrowser עם מסמך פתוח בתוכו (עד היום זה לא קרה) מצו"ב מסמך דוגמא
מסמך דוגמא.htmlיצרתי גם עוד פרוייקט עם כלום חוץ מפקד toolstrip וwebbroser כדי לבדוק מה קורה שם וזה גם קרה.
רק חבל לי לא להשתמש עם הקוד הנ"ל אחרי כל הטירחה. ובפרט שבעבר הוא כן עבד ועכשיו פתאום לא.