ããã«ã¡ã¯
WPFã§æ°ãããããžã§ã¯ãã®äœæãéå§ãããã³ã«ãããŒã«å€æ°ã®åŠå®ã«ã¢ã¿ããããããããŒã«å€æ°ãVisibilityåã«å€æããããã«ãåãã€ã³ãã£ã³ã°ã§æå®ãããç¬èªã®ã³ã³ããŒã¿ãŒãäœæããå¿
èŠããããšããèãã«æ©ãŸãããŸããã ãããŠã2ã€ã®æ°å€ã®åèšãåºåããå¿
èŠãããå ŽåããŸãã¯åã«æ°å€ã2ã§é€ç®ããå¿
èŠãããå Žåã¯ãäœãè¿œå ããã³é€ç®ããããªãã»ã©å€ãã®ã³ãŒããèšè¿°ããå¿
èŠããããŸãã
ãã®åé¡ã解決ããããã«ã1ã€ãŸãã¯è€æ°ã®æšæºçãªãã€ã³ãã£ã³ã°ã®é¡äŒŒç©ãäœæããŸãããããã«ããã1ã€ä»¥äžã®ãã€ã³ãã£ã³ã°ãœãŒã¹ããä»»æã®åŒã«ãã€ã³ãã§ããŸãã ãããã©ã®ããã«æ©èœããã©ã®ããã«äœ¿çšãããã«ã€ããŠãããã«è©³ãã説æããããšæããŸãã
æ¯èŒããŠãæšæºã®ãã€ã³ãã£ã³ã°ãšæ°ãããã€ã³ãã£ã³ã°ã䜿çšããŠè¡ãããåããã€ã³ãã£ã³ã°ïŒcïŒãã€ã³ãã£ã³ã°ïŒïŒ
å®å
ïŒ<Label> <Label.Content> <MultiBinding Conveter={x:StaticResource MyCustomConverter2}> <Binding A/> <Binding B/> <Binding C/> </MultiBinding> </Label.Content> <Label>
åŸïŒ <Label Content="{c:Binding A+B+C }" />
å®å
ïŒ <Button Visibility="{Binding IsChecked Converter={x:StaticResource NegativeBoolToVisibilityConveter}}" />
åŸïŒ <Button Visibility="{c:Binding !IsChecked}" />
ãããã®äŸãããããããã«ãæ°ãããã€ã³ãã£ã³ã°ã¯ãPathããããã£ã®1ã€ä»¥äžã®ãœãŒã¹ããããã£ããä»»æã®åŒãåãå
¥ããããšãã§ããŸãã ãã¹ãŠã®åºæ¬çãªç®è¡æŒç®ãšè«çæŒç®ãããã³è¡è¿œå æŒç®ãšäžé
æŒç®åããµããŒããããŠããŸãã
ä»ã®äŸïŒ
æ°åŠçæäœïŒ <TextBox Text="{c:Binding A+B+C}"/> <TextBox Text="{c:Binding ABC}"/> <TextBox Text="{c:Binding A*(B+C)}"/> <TextBox Text="{c:Binding 2*AB*0.5}"/> <TextBox Text="{c:Binding A/B, StringFormat={}{0:n2} --StringFormat is used}"/> <TextBox Text="{c:Binding A%B}"/> <TextBox Text="{c:Binding '(A == 1) ? 10 : 20'}"/>
è«çæŒç®ïŒ <CheckBox Content="!IsChecked" IsChecked="{c:Binding !IsChecked}"/> <TextBox Text="{c:Binding 'IsChecked and IsFull'}"/> {'and' '&&' . } <TextBox Text="{c:Binding '!IsChecked or (A > B)'}"/> {'or' '||', '||'} <TextBox Text="{c:Binding '(A == 1) and (B less= 5)'}"/> {'less=' '<=' . } <TextBox Text="{c:Binding (IsChecked || !IsFull)}"/>
ããŒã«å€ãšå¯èŠæ§ã䜿çšããïŒ <Button Content="TargetButton" Visibility="{c:Binding HasPrivileges, FalseToVisibility=Collapsed}"/> <Button Content="TargetButton" Visibility="{c:Binding !HasPrivileges}"/> <Button Content="TargetButton" Visibility="{c:Binding !HasPrivileges, FalseToVisibility=Hidden}"/>
æååã䜿çšããïŒ <TextBox Text="{c:Binding (Name + \' \' + Surname)}" /> <TextBox Text="{c:Binding (IsMan?\'Mr\':\'Ms\') + \' \' + Surname + \' \' + Name}"/>
æ°åŠã¯ã©ã¹ã§ã®äœæ¥ <TextBox Text="{c:Binding Math.Sin(A*Math.PI/180), StringFormat={}{0:n5}}"/> <TextBox Text="{c:Binding A*Math.PI}" /> <TextBox Text="{c:Binding 'Math.Sin(Math.Cos(A))'}"/>
ç¹åŸŽ
以äžã¯ãçŸåšå©çšå¯èœãªæ°ãããã€ã³ãã£ã³ã°ã®ãã¹ãŠã®æ©èœã§ãã
æ©äŒ | 詳现 | äŸ |
---|
ç®è¡æŒç® | +-/ *ïŒ
| <ã©ãã«ã®å
容= "{cïŒãã€ã³ãã£ã³ã°A * 0.5 +ïŒB / C-BïŒ
CïŒ}" /> |
è«çæŒç® | ïŒ && || ==ïŒ=ã<ã>ã<=ã> = | <TextBox Text = "{cïŒãã€ã³ãã£ã³ã°ïŒIsChecked ||ïŒIsFullïŒ}" /> |
æååãæäœãã | + | <TextBox Text = "{cïŒãã€ã³ãã£ã³ã°ïŒåå+ \ '\' +å§ïŒ}" /> |
äžé
æŒç®å | ïŒ | <TextBox Text = "{cïŒBinding 'ïŒA == 1ïŒïŒ10ïŒ20'}" /> |
boolããVisibilityãžã®èªå翻蚳 | FalseToVisibilityã¯falseã®è¡šç€ºæ¹æ³ãå®çŸ©ããŸã | <Button Visibility = "{cïŒBindingïŒIsChecked}" /> |
æ°åŠã¯ã©ã¹ã®ãµããŒã | ãã¹ãŠã®ã¡ãœãããšå®æ° | <TextBox Text = "{cïŒMath.Sinã®ãã€ã³ãïŒA * Math.PI / 180ïŒ}" /> |
èªåéé¢æ°èšç®ãšéãã€ã³ãã£ã³ã° | åŒã䜿çšããŠå察ã®ãã®ãäœæã§ããå Žåãããã¯èªåçã«è¡ããããã€ã³ãã£ã³ã°ã¯åæ¹åã«ãªããŸã |
é床ã®0ïŒ
ã®æ倱 | å
ã®ãã¹ã¯å¿åé¢æ°ã«1åã ãã³ã³ãã€ã«ããããã®åŸãå€æŽãããããããã£å€ãåžžã«çœ®æãããŸã |
å¯èŠæ§ãžã®ããŒã«
æ°ãããã€ã³ãã£ã³ã°ã¯ãããããã£ããã®ãããªã¿ã€ãã«é¢é£ä»ããããŠããå Žåãboolã¿ã€ããVisibilityã¿ã€ãã«èªåçã«å€æããŸãã ããã©ã«ãã§ã¯ãfalseã¯Visibility.Collapsedã«å€æããããšèŠãªãããŸããããã®åäœã¯ãªãã·ã§ã³ã®FalseToVisibilityããããã£ïŒCollapsedãŸãã¯HiddenïŒãèšå®ããããšã§å€æŽã§ããŸãã
<Button Visibility="{c:Binding IsChecked, FalseToVisibility=Hidden}" />
CalcBindingã®å
éšæ§é
ãã ã«ãæ¡å€§ããå¯èœæ§ã«ã€ããŠæåã«åŠãã 人ã®ããã«ãç§ã¯å°ãäœè«ããŸãã äžãã£ãã䜿çšããŠxamlããã¢ã¯ã»ã¹ãããã®ã¯ãã¹ãŠãCïŒã§èšè¿°ãããéåžžã«æ®éã®ã¯ã©ã¹ã§ãããåžžã«MarkupExtensionã¯ã©ã¹ããç¶æ¿ãããŸãã ãã®ãããªã¯ã©ã¹ã¯ããŒã¯ã¢ããæ¡åŒµæ©èœãšåŒã°ããŸãã WPFã䜿çšãããšãç¬èªã®ã«ã¹ã¿ã ããŒã¯ã¢ããæ¡åŒµæ©èœã®ã»ãããè£å®ã§ããŸãã
[1]ã®ããã«ãå€ãã®èšäºããã®ãããªè¿œå ãæžãããšã«å°å¿µããŠãã
ãããããæžãã®ã¯æ¬åœã«ç°¡åã§ãã
Bindingã¯ã©ã¹ïŒæ¬æ¥ã¯ããŒã¯ã¢ããæ¡åŒµæ©èœïŒã®ç 究ãå§ãããšããæåã«èããã®ã¯ããã®ã¯ã©ã¹ããç¶æ¿ããç¹å®ã®å Žæã§ãã€ã³ãã£ã³ã°åäœãå€æŽããããšã§ããã ããããæ®å¿µãªãããåäœãå€æŽããå¿
èŠãããProvideValueã¡ãœããã¯ãBindingBase芪ã¯ã©ã¹ã§å°å°æžã¿ïŒsealedããŒã¯ãŒãã§å®£èšïŒãšããŠããŒã¯ãããŠããããšãããããŸããã ãã®æŽçã«ãããæ°ãã空ã®ããŒã¯ã¢ããæ¡åŒµæ©èœãäœæããæšæºã®Bindingããã³MultiBindingã§äœ¿çšããããã¹ãŠã®ããããã£ãã³ããŒããå¿
èŠããããŸããã ãã¡ããããã®ãããªãœãªã¥ãŒã·ã§ã³ã§ã¯ãBindingããã³MultiBindingã®å€æŽã®ããã«ã¯ã©ã¹ãå€æŽããå¿
èŠããããŸãããWPFãé·ãééçºãããŠããªãããšãèŠããŠããã°ãããã¯ç§ãè
ãããã®ã§ã¯ãªããšæããŸãã
CalcBindingã¯ã©ã®ããã«æ§é åãããŠããŸããïŒ ProvideValueã¡ãœããã®éå§æã«ãPathããããã£ãåæãããPathã«1ã€ã®å€æ°ãå«ãŸããå ŽåãBindingãäœæãããŸãããã以å€ã®å Žåãåå€æ°ã«1ã€ã®Bindingãå«ãMultiBindingãäœæãããŸãã ãã¹ãŠã®CalcBindingããããã£ã®å€ã¯ãäœæãããBindingãŸãã¯MultiBindingã«ã¹ããŒãããã³ã³ããŒã¿ãŒã¯IConverterããã³IMultiConverterã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããPathã®ã³ã³ãã€ã«ãšçµæã®å¿åé¢æ°ã®å®è¡ãè¡ãã³ã³ããŒã¿ãŒãšããŠè»¢éãããŸãã çµæã®BindingãŸãã¯MultiBindingã¡ãœããã¯ProvideValueã¡ãœãããåŒã³åºããå€éšProvideValueã®çµæãšããŠçµæãè¿ããŸãã ãããã£ãŠãWPFã¯ãã€ã³ãã£ã³ã°ã®æšæºã¯ã©ã¹ã§åäœããç§ã®ã¯ã©ã¹ã¯äžçš®ã®ãã¡ã¯ããªãŒãšããŠæ©èœããŸãã
åè¿°ã®ããã«ãæ°ãããœãªã¥ãŒã·ã§ã³ãå€ããœãªã¥ãŒã·ã§ã³ã®é床ã倱ããªãããã«ããããã«ãæåã«ConvertãŸãã¯ConvertBackã¡ãœãããåŒã³åºããããšãã«ãPathããããã£ã§æå®ãããå
ã®åŒã1åã ãã³ã³ãã€ã«ãããŸãã ã³ã³ãã€ã«ã®çµæããœãŒã¹ããããã£ããã©ã¡ãŒã¿ãŒãšããŠåãåããã¿ãŒã²ããããããã£ããã€ã³ããããå¿åé¢æ°ãååŸããŸãã ãœãŒã¹ããããã£ã®ãããããå€æŽãããšãçµæã®é¢æ°ãæ°ãããã©ã¡ãŒã¿ãŒã§åŒã³åºãããããã«å¿ããŠæ°ããå€ãè¿ãããŸãã
æåååŒã®è§£æã¯2段éã§è¡ãããŸããæåã®è¡ã§ã¯åŒã®ããªãŒïŒSystem.Linq.Expressions.ExpressionïŒãæ§ç¯ããã2çªç®ã®è¡ã§ã¯çµæã®åŒãæšæºã¡ãœããã䜿çšããŠã³ã³ãã€ã«ãããŸãã æååããExpressionãäœæããããã«ãMicrosoftã®ããŒãµãŒããããŸããããã¯DynamicExpressionã©ã€ãã©ãª
[2]ã«ãããŸãã æ®å¿µãªããããã®ãœãªã¥ãŒã·ã§ã³ãå€æŽããã«äœ¿çšã§ããªãåé¡ãããšãã°ãã°ãæããã«ãªããŸãã
[3] ã 幞ããªããšã«ãããŒãµãŒã¯ãªãŒãã³ãœãŒã¹ã«ã¢ããããŒããããDynamicExpresso
[4]ãšåŒã°ãããã©ãŒã¯ã䜿çšããŠããã®åé¡ããã®ä»ã®åé¡ã解決ãããµããŒããããŠããã¿ã€ãã®ãªã¹ããæ¡åŒµããŸããã
詳现ãçç¥ãããšãConvertã³ã³ããŒã¿ãŒã¡ãœããã®ããžãã¯ã¯æ¬¡ã®ããã«è¡šç€ºã§ããŸãã
private Lambda compiledExpression; public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (compiledExpression == null) { var expressionTemplate = (string)parameter; compiledExpression = new Interpreter().Parse(expressionTemplate, values.Select(v => getParameter(v)).ToList()); } var result = compiledExpression.Invoke(values); return result; }
ããã¯ãã€ã³ãã£ã³ã°
ãœãŒã¹ããã¿ãŒã²ããããããã£ãžã®ãµã€ããžã®ãã€ã³ããæ£åžžã«ãã¹ããããåŸãéé¢æ°ãèªåçã«æ€çŽ¢ããå察æ¹åã«ãã€ã³ãã§ããããã«ããããšèããŸããã
éé¢æ°ãäœæã§ããããã«ããããã«ã¯ãåŒæ°ã1ã€ã ãã§ããããã®åŒæ°ã1åã ãçºçããå¿
èŠãããããšã¯æããã§ãã ãããã¯å¿
èŠã§ãããäžååãªæ¡ä»¶ã§ãã åŠæ ¡ã®æ°åŠã®ã³ãŒã¹ãããY = FïŒXïŒãY = F
1 ïŒF
2 ïŒF
3 ...ïŒF
N ïŒXïŒïŒïŒïŒãšããŠè¡šçŸã§ããè€çŽ é¢æ°ã§ããå ŽåãX = F
-1 ïŒ YïŒ= F
N -1 ïŒF
N-1 -1 ïŒF
N-2 -1 ïŒ...ïŒF
1 -1 ïŒYïŒïŒïŒïŒïŒ
ãããã£ãŠãè€éãªéé¢æ°ãäœæããã«ã¯ããã®é¢æ°ãæ§æãããã¹ãŠã®é¢æ°ã®éé¢æ°ãèŠã€ããŠãéã®é åºã§é©çšããå¿
èŠããããŸãã
ããã°ã©ãã³ã°ã«æ»ããŸãããã ããã°ã©ã ã®èŠ³ç¹ãããçŽæ¥é¢æ°ãå®è£
ããæ¢ç¥ã®åŒããªãŒããéé¢æ°ãå®è£
ããåŒããªãŒãæ§ç¯ããå¿
èŠããããŸãã Expressionã«å°å
¥ãããå¶éã«ãããäœæãããåŒããªãŒãå€æŽããããšã¯ã§ããªããããæ°ããåŒããªãŒãæ§ç¯ããå¿
èŠããããŸãã
ãããéæããããã«å¿
èŠãªããšã®äŸãèŠãŠã¿ãŸãããã ããšãã°ãå
ã®é¢æ°ã¯æ¬¡ã®ãšããã§ãã
Path = 10 + (6+5)*(3+X) - Math.Sin(6*5)
ãã®åŒã䜿çšããŠã次ã®ããªãŒãæ§ç¯ãããŸãã
Xãå«ãã·ãŒããããã¹ã®æäžéšãŸã§ã®ãã¹ãçŽç·ã§ãããæ®ãã®ããŒããäžäžã«ãããããªæ¹æ³ã§æ³åããŠãã ããã
ãã®å³ã§ã¯ãåŒã®éããªãŒãæ§ç¯ããããã«ãå€æ°Xãæã€ãªãŒãããã«ãŒããžã®ããŒãã«ãããã¹ãŠã®é¢æ°ããéã«ããPathçµæã§çœ®ãæããŠãããã¢ããªã±ãŒã·ã§ã³ã®é åºãéã«ããå¿
èŠãããããšãæããã«ãªããŸãã
å®æ°å€ãèšç®ãããã©ã³ããå転ããå¿
èŠã¯ãããŸããã ãã®çµæãéé¢æ°ãååŸããåŒã®éããªãŒãååŸããŸãã
X = ((Path - 10) + Math.Sin(6*5)) / (6 + 5) - 3
éããªãŒã®å€æ°æ€çŽ¢ãæ€èšŒãæ§ç¯ã¯ããã£ã1ã€ã®ååž°é¢æ°ã«ãã£ãŠå®è¡ãããŸãã
çŸåšã次ã®é¢æ°ãªã¹ãããµããŒããããŠããããã®éé¢æ°ã¯èªåçã«æ±ºå®ãããŸãã
- +ã-ã*ã/
- ïŒ
- Math.SinãMath.ASin
- Math.CosãMath.ACos
- Math.TanãMath.ATan
- Math.pow
- Math.log
çµæã®åŒããªãŒã¯ããã£ãŒãããã¯ãæåã«ããªã¬ãŒããããšãã«1åã ãèšç®ãããå¿åé¢æ°ã«ã³ã³ãã€ã«ãããŸãã
ãœãªã¥ãŒã·ã§ã³ã®æ¬ ç¹
ä»ã®ããã«ããã®ãœãªã¥ãŒã·ã§ã³ã«ã¯ããã€ãã®å¶éãšæ¬ ç¹ããããŸãã ç¹å®ãããæ¬ é¥ã以äžã«ãªã¹ãããŸãã
1.ïŒsourcePropertyã®1ã€ãnullã®å ŽåãtypeofïŒnullïŒã¯äœãè¿ããªããããExpressionã®äœæ段éã§åãå€å¥ã§ããªããªããŸãã ããã«ãããããšãã°ãã®ãããªåŒãæ£ããåŠçããããšãã§ããªããªããŸãã
<Label Content="{c:Binding Path = (A == null) ? 3 : 4}" />
æ®å¿µãªãããBindingã¯ã©ã¹ãããœãŒã¹ããããã£ã¿ã€ããçŽæ¥èŠã€ããããšã¯ã§ããªããããå¯äžå¯èœãªè§£æ±ºçã¯ããªãã¬ã¯ã·ã§ã³ã䜿çšããŠãœãŒã¹ããããã£ã¿ã€ããèªèããããšã§ããããã®å Žåã¯ãSourceïŒRelativeSourceãElementNameãªã©ïŒãæ€çŽ¢ããŠããã€ã³ãã£ã³ã°æ©èœã®ååãå®è£
ããå¿
èŠããããŸãã ããããããã®åé¡ã«å¯Ÿãã代æ¿ãœãªã¥ãŒã·ã§ã³ãããã®ã§ããã®ãããã¯ã«é¢ããææ¡ãåãã§ããŸãã
2.ïŒxamlããŒã¯ã¢ããã¯xmlããŒã¯ã¢ããã§ãããããå€æ°ã®æåãããšãã°éå§ã¿ã°ãã¢ã³ããµã³ãã¢ã€ã³ã³ã¯çŠæ¢ãããŠããŸããããã¯ããmoreãããã³ãlogical ANDãã®èšå·ãæå³ããŸãã çŠæ¢ãããæåããéããããã«ãPathã¯ãããã®æŒç®åã®ä»£ããã«ä»¥äžã«ç€ºãããã€ãã®çœ®æã䜿çšããŸãã
ãªãã¬ãŒã¿ãŒ | ãã¹ã®çœ®æ | ã泚æ |
---|
&& | ãã㊠|
|| | ãŸã㯠| 察称æ§ã®ããã«å°å
¥ããªãã·ã§ã³ |
< | å°ãªã |
<= | å°ãªã= |
3.ïŒCalcBindingã§ç¬èªã®ã³ã³ããŒã¿ãŒãèšå®ããããšã¯ã§ããŸããã ç§ã¯ãã®ãããªæ©äŒãå¿
èŠãšããã·ããªãªãæãã€ããŸããã§ããã®ã§ãäœãææ¡ãããã°ãç§ã¯ããããèªãã§ããããã§ãã
ãããžã§ã¯ããžã®ãªã³ã¯ïŒ
ã©ã€ãã©ãªã¯
githubã§å
¥æã§ããŸãã ãããžã§ã¯ãã«ã¯ãã©ã€ãã©ãªã®ãœãŒã¹ã³ãŒãããã¹ãŠã®æ©èœã䜿çšããæ¬æ ŒçãªäŸãããã³ãã¹ããå«ãŸããŠããŸãã ã©ã€ãã©ãªã®ãã²ããããã±ãŒãžãäœæãããŸããã
www.nuget.org/packages/CalcBinding䜿çšããããœãŒã¹ãžã®åç
§ïŒ
[1]
10rem.net/blog/2011/03/09/ã«ã¹ã¿ã ããŒã¯ã¢ããæ¡åŒµæ©èœã®äœæ-wpf-and-soon-silverlight[2]
weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-libraryèšäº
msdn.microsoft.com/en-us/vstudio/bb894665.aspxããŠã³ããŒããªã³ã¯
[3]
connect.microsoft.com/VisualStudio/feedback/details/677766/system-linq-dynamic-culture-related-floating-point-parsing-error[4]
github.com/davideicardi/DynamicExpresso