2017-04-23 4 views
1

Je travaille avec les contrôles InkCanvas et InkToolbar et j'ai un petit problème d'interface utilisateur chaque fois que je mets à jour les attributs d'encrage actuels pour le canevas.InkToolbar UI désynchronisé avec la cible InkCanvas lors de la mise à jour de InkDrawingAttributes

Disons que je ces deux contrôles dans une page:

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

Et puis dans le gestionnaire d'événements Loaded de la page que je quelque chose comme ceci pour définir les attributs d'encrage initial:

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

L'outil utilisé est correctement modifié. Par exemple, si je définis les attributs pour utiliser un surligneur jaune, lorsque je commence à dessiner, j'utilise un surligneur comme prévu.

Mais, la question est que l'interface utilisateur du contrôle InkToolbar est pas mis à jour, et il montre encore l'outil par défaut que celui utilisé (la couleur utilisée pour le surligneur est pas mis à jour non plus, donc si j'initialise les attributs avec un surligneur orange, la barre d'outils affichera toujours la couleur jaune par défaut).

Est-ce intentionnellement ou est-ce un bug dans le contrôle? Je ne vois pas un moyen de définir explicitement le InkDrawingAttributes dans la barre d'outils, car cette propriété est en lecture seule (et définir manuellement ses propriétés imbriquées ne semble pas affecter l'interface utilisateur de la barre d'outils de toute façon).

EDIT: depuis la InkToolbar ne met pas à jour son interface utilisateur lorsque les attributs du changement de contrôle cible InkCanvas, je suis venu avec ce code pour essayer pour résoudre le problème:

// 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; 

Maintenant, le bouton droit est sélectionné correctement, mais je n'ai toujours aucun moyen de définir une taille/couleur de crayon spécifique. Je n'utiliserai qu'une couleur qui est réellement présente dans la palette d'origine, c'est pourquoi je ne m'inquiète pas de ce qui pourrait arriver si j'essayais de définir une couleur qui n'est pas prédéfinie dans le contrôle InkToolbar. En fin de compte, je veux juste enregistrer/restaurer les paramètres de dessin d'encre de l'utilisateur entre différentes sessions, et je voudrais que l'interface utilisateur du InkToolbar le suive également. Y a-t-il un moyen de le faire ou dois-je me contenter de choisir le bon bouton d'outil (avec la couleur/taille désynchronisée)?

Merci pour votre aide!

+0

il y a un problème dans votre code édité , 'DrawingCanvas.InkPresenter.UpdateDefaultDrawingAttributes (attributs); 'devrait être appelé _after_' Toolbar.ActiveTool = button; ', de sorte que l'attribut de dessin ne soit pas écrasé à nouveau. – kennyzx

+0

@kennyzx Ouais je sais que, les deux extraits de code dans ma question ne doivent pas être considérés comme ordonnés, j'ai ajouté le deuxième après avoir posté la question initiale. J'utilise actuellement le second extrait pour au moins mettre le bon bouton dans le 'InkToolbar', puis le code dans le premier snippet pour charger le' InkDrawingAttributes' que je veux utiliser. – Sergio0694

Répondre

0

a finalement réussi à comprendre comment résoudre ce problème, voici le code que je suis venu avec:

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; 
} 

Remarque: comme aussi kennyzx souligné, ce code doit être appelé avant que la méthode UpdateDefaultDrawingAttributes de la cible InkPresenter objet.

Modifier: J'ai réalisé cette méthode IndexOf était une petite méthode d'extension je l'ai écrit et non une méthode dans la bibliothèque standard, voici le code juste au cas où:

///<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

Lorsque vous définissez la propriété TargetInkCanvas, il est un « sens unique de liaison », les paramètres de la barre d'outils se propagent à la InkCanvas associée, mais si vous définissez les InkDrawingAttributes des InkCanvas dans le code derrière, ils ne sont pas reflété dans la barre d'outils.

Ceci est voulu. Vous pouvez définir un InkDrawingAttributes dans le code avec une couleur qui n'est pas disponible dans la palette, que pensez-vous que la barre d'outils mise à jour reflétera votre choix? Si vous souhaitez les synchroniser, vous devez écrire du code pour mettre à jour la barre d'outils, par exemple, en définissant la propriété ActiveTool. Je ne sais pas s'il est possible de refléter le InkDrawingAttributes actuel dans la barre d'outils, cependant.

+0

J'ai modifié ma question et j'ai ajouté un extrait de code pour sélectionner le bon bouton d'outil, comme suggéré, mais cela ne résout toujours pas le problème car je n'ai pas trouvé de moyen de restaurer la taille de crayon précédente/couleur aussi. Merci! – Sergio0694

+0

Comme je ne trouve aucune API liée à la mise à jour de la couleur/pensize dans le menu déroulant des boutons par défaut, votre exigence pourrait être assez difficile, voire impossible à réaliser. Je trouve quelque chose sur "inktoolbar customisé" mais semble assez compliqué. Il est sûr de dire que la barre d'outils n'est pas conçue pour se synchroniser avec inkcanvas en premier lieu. – kennyzx

+0

Juste compris comment faire, voir ma réponse ci-dessous. Et merci pour votre aide et vos suggestions! :) – Sergio0694