2017-04-23 18 views
1

我正在使用InkCanvasInkToolbar控件,並且每次更新畫布的當前墨跡屬性時都會遇到小的UI故障。InkToolbar UI在更新InkDrawingAttributes時與目標InkCanvas不同步

比方說,我有這兩個控件在一個頁面:

<InkToolbar TargetInkCanvas="{x:Bind DrawingCanvas}"/> 
<InkCanvas x:Name="DrawingCanvas"/> 

然後在頁面Loaded事件處理程序我有這樣的事情來設置初始墨屬性:

// Update the attributes 
InkDrawingAttributes attributes = new InkDrawingAttributes 
{ 
    PenTip = PenTipShape.Circle, 
    Color = Colors.Red, 
    // And so on... 
}; 
DrawingCanvas.InkPresenter.UpdateDefaultDrawingAttributes(attributes); 

正在使用的工具已正確更改,因此例如,如果我將屬性設置爲使用黃色熒光筆,則當我開始繪畫時,實際上正在按照預期使用熒光筆。

,問題是,InkToolbar控制的用戶界面沒有更新,它仍然顯示了默認的工具爲一個使用(使用的顏色熒光筆沒有更新要麼,所以如果我用橙色熒光筆初始化屬性,工具欄仍將顯示默認的黃色)。

這是設計還是控制中的錯誤?我沒有看到在工具欄中明確設置InkDrawingAttributes的方法,因爲該屬性是隻讀的(並且手動設置其嵌套屬性似乎不會影響工具欄UI)。

編輯:因爲InkToolbar不更新當目標InkCanvas控制改變的屬性,我想出了這個代碼嘗試解決這一問題的UI:

// Assume I already have the "attributes" variable with my desired settings 
InkToolbarTool tool; 
if (attributes.DrawAsHighlighter) tool = InkToolbarTool.Highlighter; 
else tool = attributes.Kind == InkDrawingAttributesKind.Default ? InkToolbarTool.BallpointPen : InkToolbarTool.Pencil; 
InkToolbarToolButton button = Toolbar.GetToolButton(tool); 
Toolbar.ActiveTool = button; 

現在,右鍵可以正確選擇,但我仍然無法設置特定的筆大小/顏色。 我只會使用原始調色板中實際存在的顏色,這就是爲什麼我不擔心如果我嘗試設置在InkToolbar控件中未預定義的顏色會發生什麼情況。

最後,我只想保存/恢復不同會話之間的用戶墨跡繪圖設置,並且我希望InkToolbar的用戶界面也可以遵循這一點。有沒有辦法做到這一點,還是我必須解決只是選擇正確的工具按鈕(顏色/大小不同步)?

感謝您的幫助!

+0

有一個在您編輯的代碼中的問題,'DrawingCanvas.InkPresenter.UpdateDefaultDrawingAttributes(attributes); '應該被稱爲_after_'Toolbar.ActiveTool = button;',以便繪圖屬性不會再被覆蓋。 – kennyzx

+0

@kennyzx是的我知道,我的問題中的兩個代碼片段不會被視爲有序,我在發佈最初的問題後添加了第二個代碼片段。我正在使用第二個片段來至少在「InkToolbar」中設置正確的按鈕,然後在第一個片段中的代碼加載我想要使用的右側「InkDrawingAttributes」。 – Sergio0694

回答

0

終於設法瞭解如何解決這個問題,下面的代碼我想出了:

void SetupInkToolbar(this InkToolbar toolbar, InkToolbarTool tool, Color color, double thickness) 
{ 
    InkToolbarToolButton button = toolbar.GetToolButton(tool); 
    if (button is InkToolbarPenButton typed) // Only adjust the UI if the tool is either a pen, a pencil or an highlighter 
    { 
     Color[] colors = typed.Palette.Select(p => (p as SolidColorBrush)?.Color ?? Colors.Black).ToArray(); 
     int index = colors.IndexOf(c => c.Equals(color)); 
     if (index >= 0) typed.SelectedBrushIndex = index; // Get the right brush index for the given color 
     typed.SelectedStrokeWidth = thickness; // Adjust the brush thickness too 
    } 
    toolbar.ActiveTool = button; 
} 

注意:成也kennyzx指出,此代碼應目標的UpdateDefaultDrawingAttributes方法之前被調用InkPresenter對象。

編輯:我意識到IndexOf方法是一個小的擴展方法我寫的,而不是在標準庫的方法,這裏的代碼,以防萬一:

///<summary>Finds the index of the first item matching an expression in an enumerable</summary> 
///<param name="items">The enumerable to search</param> 
///<param name="predicate">The expression to test the items against</param> 
///<returns>The index of the first matching item, or -1 if no items match</returns> 
public static int IndexOf<T>([NotNull] this IEnumerable<T> items, [NotNull] Func<T, bool> predicate) 
{ 
    int index = 0; 
    foreach (T item in items) 
    { 
     if (predicate(item)) return index; 
     index++; 
    } 
    return -1; 
} 
1

當設置TargetInkCanvas屬性,它是一種「單向綁定」,在工具欄的設置被傳播到相關InkCanvas,但如果你設置InkCanvas的InkDrawingAttributes背後代碼,他們不反映在工具欄中。

這是設計。您可以在後面的代碼中設置一個InkDrawingAttributes,其顏色在調色板中不可用,您希望工具欄更新以反映您的選擇?如果你想同步它們,你需要編寫代碼來更新工具欄,比如設置ActiveTool屬性。不過,我不知道是否可以在工具欄中反映當前的InkDrawingAttributes

+0

我編輯了我的問題,並添加了一段代碼來選擇正確的工具按鈕,正如建議的那樣,但它仍然不能解決問題,因爲迄今爲止我還沒有找到一種方法來恢復以前的筆大小/顏色。謝謝! – Sergio0694

+0

由於在默認按鈕的彈出窗口中我沒有找到與更新顏色/ pensize有關的任何API,所以如果不是不可能實現的話,您的需求可能會非常困難。我確實在「自定義的inktoolbar」上找到了一些東西,但看起來相當複雜。可以安全地說,工具欄不是設計爲首先與inkcanvas同步的。 – kennyzx

+0

只是想出瞭如何做到這一點,請參閱下面的答案。並感謝您的幫助和您的建議! :) – Sergio0694