c# - ContentPresenter steals resources? -
in simple view want display 2 buttons, have contents images, provided via resources in style.xaml loaded in app.xaml.
<bitmapimage x:key="addicon" urisource="pack://application:,,,/wpftestbench;component/images/plus.png"></bitmapimage> <bitmapimage x:key="removeicon" urisource="pack://application:,,,/wpftestbench;component/images/minus.png"></bitmapimage> <style x:key="addbuttonwithiconstyle" targettype="{x:type button}"> <setter property="content"> <setter.value> <image source="{dynamicresource addicon}" stretch="none" verticalalignment="center" horizontalalignment="center"/> </setter.value> </setter> </style> <style x:key="removebuttonwithiconstyle" targettype="{x:type button}"> <setter property="content"> <setter.value> <image source="{dynamicresource removeicon}" stretch="none" verticalalignment="center" horizontalalignment="center"/> </setter.value> </setter> </style>
in view use styles this:
<dockpanel margin="0,0,5,0" dockpanel.dock="bottom" lastchildfill="false" > <button command="{binding deletecommand}" dockpanel.dock="right" style="{staticresource removebuttonwithiconstyle}"/> <button command="{binding addcommand}" dockpanel.dock="right" margin="5,0" style="{staticresource addbuttonwithiconstyle}"/> </dockpanel>
so far looks good. when add view view via contentpresenter, has same content (again above described button styles) display of first 2 buttons (of parent view) not work anymore. ist 2 small circles button functionality.
<contentpresenter content="{binding someembeddedviewmodel, updatesourcetrigger=propertychanged}"/>
why happen? contentpresenter somehow prevent share resources?
diagnosis
the core reason of behavior element can appear once in visual tree.
first of all, resources in resourcedictionary
default shared, i.e. every time fetch resource particular key, same instance. in case, same instance of style
, means there's 1 instance of image
(for each style).
so if apply same style 2 buttons, framework tries put same image
instance in 2 different places, not allowed. avoid that, upon attempt load image visual tree, if in visual tree, unloaded previous location first.
that's why image visible in last button (in order in loaded).
solution
there 2 solutions problem.
1. disable resource sharing
you can disable resource sharing each time fetch resource resourcedictionary
new instance of resource. in order that, set x:shared="false"
on resource:
<style x:key="addbuttonwithiconstyle" x:shared="false" targettype="{x:type button}"> (...) </style>
2. use contenttemplate
in style
instead of putting image content of button, define contenttemplate
, realized separately each button applied (so each button gets own instance of image):
<style x:key="removebuttonwithiconstyle" targettype="{x:type button}"> <setter property="contenttemplate"> <setter.value> <datatemplate> <image source="{dynamicresource removeicon}" stretch="none" verticalalignment="center" horizontalalignment="center"/> </datatemplate> </setter.value> </setter> </style>
personally i'd advise use second solution, since that's purpose of templates in wpf.
Comments
Post a Comment