wpf - C# Set translatetransform X and Y property relative to MainWindow -
i have wrappanel hosted inside itemscontrol wrapped in scrollviewer. items in wrappanel populated binding. every item has datatemplate datatrigger. trigger suposed animate item center of screen. trying translatetransform, problem x , y properties of translatetransform relative item , not host container, every item has different animation. seen here:
the item template xaml:
<datatemplate x:key="countryitemtemplate"> <grid x:name="gridmain" height="auto" width="auto" margin="3" rendertransformorigin="0 0" panel.zindex="{binding isvisible, mode=oneway, updatesourcetrigger=propertychanged}"> <materialdesign:card x:name="cardmain" height="350" width="310" rendertransformorigin="0.5, 0.5" materialdesign:shadowassist.shadowdepth="depth1" uniformcornerradius="3"> <grid background="transparent"> <grid.rowdefinitions> <rowdefinition height="50*"/> <rowdefinition height="50*"/> </grid.rowdefinitions> <rectangle grid.row="0"> <rectangle.fill> <imagebrush imagesource="{binding imageurl, mode=oneway, updatesourcetrigger=propertychanged}"/> </rectangle.fill> </rectangle> <textblock grid.row="1" foreground="black" fontweight="regular" fontsize="25" horizontalalignment="left" verticalalignment="top" margin="16 24 0 0" text="{binding name, mode=twoway, updatesourcetrigger=propertychanged}"/> <button grid.row="1" style="{dynamicresource materialdesigntoolbutton}" content="edit" fontsize="15" width="85" height="35" horizontalalignment="right" verticalalignment="bottom" margin="0 0 16 24" command="{binding isineditmodetogglecommand}"/> </grid> <materialdesign:card.rendertransform> <transformgroup> <scaletransform/> <translatetransform/> </transformgroup> </materialdesign:card.rendertransform> </materialdesign:card> </grid> <datatemplate.triggers> <datatrigger binding="{binding isineditmode, mode=oneway, updatesourcetrigger=propertychanged}" value="true"> <datatrigger.enteractions> <beginstoryboard> <storyboard> <doubleanimation storyboard.targetname="cardmain" storyboard.targetproperty="(uielement.rendertransform).children[1].(translatetransform.x)" to="300" by="1" duration="0:0:2"> <doubleanimation.easingfunction> <exponentialease easingmode="easeinout" exponent="16"/> </doubleanimation.easingfunction> </doubleanimation> <doubleanimation storyboard.targetname="cardmain" storyboard.targetproperty="(uielement.rendertransform).children[1].(translatetransform.y)" to="400" by="1" duration="0:0:2"> <doubleanimation.easingfunction> <exponentialease easingmode="easeinout" exponent="16"/> </doubleanimation.easingfunction> </doubleanimation> </storyboard> </beginstoryboard> </datatrigger.enteractions> </datatrigger> </datatemplate.triggers> </datatemplate>
i tried use uielement.translatepoint :
the whole usercontrol is:
<usercontrol x:class="nikolalukovic.customsofficeapp.desktop.views.countryusercontrol" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:domain="clr-namespace:nikolalukovic.customsofficeapp.desktop.domainmodels" xmlns:helpers="clr-namespace:nikolalukovic.customsofficeapp.desktop.helpers" xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" xmlns:materialdesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:validationrules="clr-namespace:nikolalukovic.customsofficeapp.desktop.helpers.validationrules" xmlns:views="clr-namespace:nikolalukovic.customsofficeapp.desktop.views" xmlns:viewmodels="clr-namespace:nikolalukovic.customsofficeapp.desktop.viewmodels" xmlns:local="clr-namespace:nikolalukovic.customsofficeapp.desktop.views" mc:ignorable="d" d:designheight="600" d:designwidth="900"> <usercontrol.cachemode> <bitmapcache/> </usercontrol.cachemode> <i:interaction.triggers> <i:eventtrigger eventname="loaded"> <i:invokecommandaction command="{binding loaddatacommand}" commandparameter="{binding elementname=icmain}"/> </i:eventtrigger> </i:interaction.triggers> <usercontrol.datacontext> <viewmodels:countryviewmodel/> </usercontrol.datacontext> <usercontrol.resources> <resourcedictionary> <resourcedictionary.mergeddictionaries> <resourcedictionary source="../resources/countryitemstyle.xaml"/> <resourcedictionary source="../resources/icons.xaml"/> <resourcedictionary source="../resources/materialdesignicons.xaml"/> <resourcedictionary source="pack://application:,,,/materialdesignthemes.wpf;component/themes/materialdesigntheme.button.xaml" /> <resourcedictionary source="pack://application:,,,/materialdesignthemes.wpf;component/themes/materialdesigntheme.shadows.xaml" /> <resourcedictionary source="pack://application:,,,/materialdesignthemes.wpf;component/themes/materialdesigntheme.togglebutton.xaml" /> </resourcedictionary.mergeddictionaries> <booleantovisibilityconverter x:key="booltovisconverter"/> </resourcedictionary> </usercontrol.resources> <materialdesign:dialoghost> <grid> <grid.rowdefinitions> <rowdefinition height="*"/> <rowdefinition height="100"/> </grid.rowdefinitions> <grid.columndefinitions> <columndefinition width="*"/> <columndefinition width="100"/> </grid.columndefinitions> <scrollviewer grid.row="0" grid.column="0" grid.rowspan="2" grid.columnspan="2" verticalscrollbarvisibility="auto"> <itemscontrol horizontalcontentalignment="stretch" verticalcontentalignment="stretch" x:name="icmain" itemtemplate="{staticresource countryitemtemplate}" itemssource="{binding countries, mode=oneway, updatesourcetrigger=propertychanged}"> <itemscontrol.itemspanel> <itemspaneltemplate> <wrappanel/> </itemspaneltemplate> </itemscontrol.itemspanel> </itemscontrol> </scrollviewer> <button width="45" height="45" style="{dynamicresource materialdesignfloatingactionaccentbutton}" grid.column="1" grid.row="1" horizontalalignment="left" verticalalignment="top" margin="0 10 0 0"> <viewbox width="24" height="24"> <canvas width="24" height="24"> <path data="m19,13h13v19h11v13h5v11h11v5h13v11h19v13z" fill="white" /> </canvas> </viewbox> </button> </grid> </materialdesign:dialoghost> </usercontrol>
the datacontext viewmodel:
public class countryviewmodel : baseviewmodel { private observablecollection<countryitem> countries; private delegatecommand<itemscontrol> loaddatacommand; public countryviewmodel ( ) { viewmodelfinder.add(this); } public observablecollection<countryitem> countries { { return countries; } set { this.countries = value; this.notifypropertychanged(); } } public delegatecommand<itemscontrol> loaddatacommand { { if ( this.loaddatacommand == null ) this.loaddatacommand = new delegatecommand<itemscontrol>(async icmain => await loaddatamethod(icmain)); return this.loaddatacommand; } } private async task loaddatamethod (itemscontrol icmain) { if ( this.countries == null ) { var countries = await countryservice.instance.getallasync(); this.countries = new observablecollection<countryitem>(); var util = new util(); foreach ( var country in countries.take(40) ) { var countryitem = new countryitem { name = country.name, iso2 = country.iso2, isoalpha3 = country.isoalpha3, isounm49numerical = country.isounm49numerical, id = country.id }; var imagebytes = await util.getimagebytesasync(country.countryflagurl); countryitem.imageurl = country.countryflagurl; this.countries.add(countryitem); countryitem.this = icmain.itemcontainergenerator.containerfromitem(countryitem) uielement; } } } }
class represents item in wrappanel:
public class countryitem : observableobject { private bool isenabled = true; private bool isineditmode; private bool isvisible = true; private delegatecommand isineditmodetogglecommand; private string name; private string iso2; private string isoalpha3; private int isounm49numerical; private string imageurl; private guid id; private uielement @this; public countryitem ( ) { } public bool isenabled { { return isenabled; } set { this.isenabled = value; this.notifypropertychanged(); } } [required(allowemptystrings = false, errormessage = "name required.")] public string name { { return this.name; } set { this.name = value; this.notifypropertychanged(); } } [required(allowemptystrings = false, errormessage = "iso2 required.")] public string iso2 { { return this.iso2; } set { this.iso2 = value; this.notifypropertychanged(); } } [required(allowemptystrings = false, errormessage = "iso alpha3 required.")] public string isoalpha3 { { return this.isoalpha3; } set { this.isoalpha3 = value; this.notifypropertychanged(); } } [required(allowemptystrings = false, errormessage = "iso un m49 numerical required.")] public int isounm49numerical { { return this.isounm49numerical; } set { this.isounm49numerical = value; this.notifypropertychanged(); } } public string imageurl { { return imageurl; } set { this.imageurl = value; this.notifypropertychanged(); } } public guid id { { return id; } set { this.id = value; } } public bool isineditmode { { return isineditmode; } set { this.isineditmode = value; this.notifypropertychanged(); } } public delegatecommand isineditmodetogglecommand { { if ( this.isineditmodetogglecommand == null ) this.isineditmodetogglecommand = new delegatecommand(isineditmodetogglemethod); return this.isineditmodetogglecommand; } } public bool isvisible { { return isvisible; } set { this.isvisible = value; this.notifypropertychanged(); } } public uielement { { return this.@this; } set { this.@this = value; this.notifypropertychanged(); } } private void isineditmodetogglemethod ( ) { var countryviewmodel = viewmodelfinder.findone<countryviewmodel>(); countryviewmodel.countries.where(x=>x.id != this.id).tolist().foreach(ci => ci.isvisible = false); this.this.translatepoint(new point(400, 500), application.current.mainwindow) this.isineditmode = !this.isineditmode; } }
you can translate coordinates uielement.translatepoint
function. need way use translated value in animation, there should multiple ways accomplish this.
one option be, have dedicated currentedititem
outside collection , modify window content template based on, whether property set. way, relation between window , item should easier model. i'm sure possible throw binding , converter on to
values, in order have them translate window-to-item coordinate values.
for example, converter instantiated static resource on window reference window , converterparameter
item allow you, convert incomming value between window , item coordinates.
Comments
Post a Comment