重新想象 Windows 8 Store Apps (16) - 控件基础: 依赖属性, 附加属性, 控件的继承关系,
路由事件和命中测试
作者:webabcd
介绍
重新想象 Windows 8 Store Apps
之 控件基础
- DependencyProperty - 依赖属性
- AttachedProperty - 附加属性
- 控件的继承关系
- 路由事件和命中测试
示例
1、开发一个具有 DependencyProperty 和 AttachedProperty
的自定义控件
MyControls/themes/generic.xaml
<span><</span><span>ResourceDictionary
</span><span>xmlns</span><span>="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span><span>
xmlns:x</span><span>="http://schemas.microsoft.com/winfx/2006/xaml"</span><span>
xmlns:local</span><span>="using:MyControls"</span><span>></span><span><!--</span><span>
自定义控件的样式在本文件(themes/generic.xaml)中定义
整合外部 ResourceDictionary
</span><span>--></span><span><</span><span>ResourceDictionary.MergedDictionaries</span><span>></span><span><</span><span>ResourceDictionary </span><span>Source</span><span>="ms-appx:///MyControls/themes/MyControl.xaml"</span><span>/></span><span></</span><span>ResourceDictionary.MergedDictionaries</span><span>></span><span></</span><span>ResourceDictionary</span><span>></span>MyControls/themes/MyControl.xaml
<span><</span><span>ResourceDictionary
</span><span>xmlns</span><span>="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span><span>
xmlns:x</span><span>="http://schemas.microsoft.com/winfx/2006/xaml"</span><span>
xmlns:local</span><span>="using:MyControls"</span><span>></span><span><</span><span>Style </span><span>TargetType</span><span>="local:MyControl"</span><span>></span><span><</span><span>Setter </span><span>Property</span><span>="Template"</span><span>></span><span><</span><span>Setter.Value</span><span>></span><span><</span><span>ControlTemplate </span><span>TargetType</span><span>="local:MyControl"</span><span>></span><span><</span><span>Border </span><span>Background</span><span>="</span><span>{TemplateBinding Background}</span><span>"</span><span> BorderBrush</span><span>="</span><span>{TemplateBinding BorderBrush}</span><span>"</span><span> BorderThickness</span><span>="</span><span>{TemplateBinding BorderThickness}</span><span>"</span><span>></span><span><</span><span>StackPanel</span><span>></span><span><!--</span><span>绑定自定义依赖属性</span><span>--></span><span><</span><span>TextBlock </span><span>Text</span><span>="</span><span>{TemplateBinding Title}</span><span>"</span><span> Foreground</span><span>="White"</span><span> FontSize</span><span>="26.667"</span><span>/></span><span><!--</span><span>绑定自定义附加属性</span><span>--></span><span><</span><span>TextBlock </span><span>Text</span><span>="</span><span>{TemplateBinding local:MyAttachedProperty.SubTitle}</span><span>"</span><span> Foreground</span><span>="White"</span><span> FontSize</span><span>="14.667"</span><span>/></span><span></</span><span>StackPanel</span><span>></span><span></</span><span>Border</span><span>></span><span></</span><span>ControlTemplate</span><span>></span><span></</span><span>Setter.Value</span><span>></span><span></</span><span>Setter</span><span>></span><span></</span><span>Style</span><span>></span><span></</span><span>ResourceDictionary</span><span>></span>MyControls/MyControl.cs
<span>/*</span><span>
* 开发一个自定义控件,用于演示依赖属性(Dependency Property)和附加属性(Attached Property)
*
* 依赖属性:可以用于样式, 模板, 绑定, 动画
* 附加属性:全局可用的依赖属性
</span><span>*/</span><span>using</span><span> Windows.UI.Xaml.Controls;
</span><span>using</span><span> Windows.UI.Xaml;
</span><span>namespace</span><span> MyControls
{
</span><span>///</span><span><summary></span><span>///</span><span> 用于依赖属性的演示
</span><span>///</span><span></summary></span><span>public</span><span>class</span><span> MyControl : Control
{
</span><span>public</span><span> MyControl()
{
</span><span>//</span><span> 指定默认样式为 typeof(MyControl),即对应:<Style xmlns:local="using:MyControls" TargetType="local:MyControl" /></span><span>this</span>.DefaultStyleKey = <span>typeof</span><span>(MyControl);
}
</span><span>//</span><span> 通过 DependencyObject.GetValue() 和 DependencyObject.SetValue() 访问依赖属性,这里由 Title 属性封装一下,以方便对依赖属性的访问</span><span>public</span><span>string</span><span> Title
{
</span><span>get</span> { <span>return</span> (<span>string</span><span>)GetValue(TitleProperty); }
</span><span>set</span><span> { SetValue(TitleProperty, value); }
}
</span><span>//</span><span> 注册一个依赖属性</span><span>public</span><span>static</span><span>readonly</span> DependencyProperty TitleProperty =<span>
DependencyProperty.Register(
</span><span>"</span><span>Title</span><span>"</span>, <span>//</span><span> 依赖属性的名称</span><span>typeof</span>(<span>string</span>), <span>//</span><span> 依赖属性的数据类型</span><span>typeof</span>(MyControl), <span>//</span><span> 依赖属性所属的类</span><span>new</span> PropertyMetadata(<span>""</span>, PropertyMetadataCallback)); <span>//</span><span> 指定依赖属性的默认值,以及值发生改变时所调用的方法</span><span>private</span><span>static</span><span>void</span><span> PropertyMetadataCallback(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
</span><span>object</span> newValue = args.NewValue; <span>//</span><span> 发生改变之后的值</span><span>object</span> oldValue = args.OldValue; <span>//</span><span> 发生改变之前的值</span><span> }
}
</span><span>///</span><span><summary></span><span>///</span><span> 用于附加属性的演示
</span><span>///</span><span></summary></span><span>public</span><span>class</span><span> MyAttachedProperty
{
</span><span>//</span><span> 获取附加属性</span><span>public</span><span>static</span><span>string</span><span> GetSubTitle(DependencyObject obj)
{
</span><span>return</span> (<span>string</span><span>)obj.GetValue(SubTitleProperty);
}
</span><span>//</span><span> 设置附加属性</span><span>public</span><span>static</span><span>void</span> SetSubTitle(DependencyObject obj, <span>string</span><span> value)
{
obj.SetValue(SubTitleProperty, value);
}
</span><span>//</span><span> 注册一个附加属性</span><span>public</span><span>static</span><span>readonly</span> DependencyProperty SubTitleProperty =<span>
DependencyProperty.RegisterAttached(
</span><span>"</span><span>SubTitle</span><span>"</span>, <span>//</span><span> 附加属性的名称</span><span>typeof</span>(<span>string</span>), <span>//</span><span> 附加属性的数据类型</span><span>typeof</span>(MyAttachedProperty), <span>//</span><span> 附加属性所属的类</span><span>new</span> PropertyMetadata(<span>""</span>, PropertyMetadataCallback)); <span>//</span><span> 指定附加属性的默认值,以及值发生改变时所调用的方法</span><span>private</span><span>static</span><span>void</span><span> PropertyMetadataCallback(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
</span><span>object</span> newValue = args.NewValue; <span>//</span><span> 发生改变之后的值</span><span>object</span> oldValue = args.OldValue; <span>//</span><span> 发生改变之前的值</span><span> }
}
}</span>
2、演示依赖属性的使用
Controls/Basic/DependencyPropertyDemo.xaml
<span><</span><span>Page
</span><span>x:Class</span><span>="XamlDemo.Controls.Basic.DependencyPropertyDemo"</span><span>
xmlns</span><span>="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span><span>
xmlns:x</span><span>="http://schemas.microsoft.com/winfx/2006/xaml"</span><span>
xmlns:local</span><span>="using:XamlDemo.Controls.Basic"</span><span>
xmlns:d</span><span>="http://schemas.microsoft.com/expression/blend/2008"</span><span>
xmlns:mc</span><span>="http://schemas.openxmlformats.org/markup-compatibility/2006"</span><span>
xmlns:myControls</span><span>="using:MyControls"</span><span>
mc:Ignorable</span><span>="d"</span><span>></span><span><</span><span>Grid </span><span>Background</span><span>="Transparent"</span><span>></span><span><</span><span>StackPanel </span><span>Margin</span><span>="120 0 0 0"</span><span>></span><span><!--</span><span>
演示如何开发和使用自定义依赖属性(本例所用到的自定义控件请参看:MyControls/MyControl.cs)
</span><span>--></span><span><</span><span>myControls:MyControl </span><span>Background</span><span>="Blue"</span><span> BorderBrush</span><span>="Yellow"</span><span> BorderThickness</span><span>="1"</span><span> Width</span><span>="100"</span><span> HorizontalAlignment</span><span>="Left"</span><span>
Title</span><span>="</span><span>{Binding Value, ElementName=slider}</span><span>"</span><span>/></span><span><</span><span>Slider </span><span>Name</span><span>="slider"</span><span> Width</span><span>="100"</span><span> Minimum</span><span>="0"</span><span> Maximum</span><span>="200"</span><span> IsThumbToolTipEnabled</span><span>="False"</span><span> HorizontalAlignment</span><span>="Left"</span><span>/></span><span></</span><span>StackPanel</span><span>></span><span></</span><span>Grid</span><span>></span><span></</span><span>Page</span><span>></span>
3、演示附加属性的使用
Controls/Basic/AttachedPropertyDemo.xaml
<span><</span><span>Page
</span><span>x:Class</span><span>="XamlDemo.Controls.Basic.AttachedPropertyDemo"</span><span>
xmlns</span><span>="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span><span>
xmlns:x</span><span>="http://schemas.microsoft.com/winfx/2006/xaml"</span><span>
xmlns:local</span><span>="using:XamlDemo.Controls.Basic"</span><span>
xmlns:d</span><span>="http://schemas.microsoft.com/expression/blend/2008"</span><span>
xmlns:mc</span><span>="http://schemas.openxmlformats.org/markup-compatibility/2006"</span><span>
xmlns:myControls</span><span>="using:MyControls"</span><span>
mc:Ignorable</span><span>="d"</span><span>></span><span><</span><span>Grid </span><span>Background</span><span>="Transparent"</span><span>></span><span><</span><span>StackPanel </span><span>Margin</span><span>="120 0 0 0"</span><span>></span><span><!--</span><span>
演示如何开发和使用自定义附加属性(本例所用到的自定义控件请参看:MyControls/MyControl.cs)
</span><span>--></span><span><</span><span>myControls:MyControl </span><span>Background</span><span>="Blue"</span><span> BorderBrush</span><span>="Yellow"</span><span> BorderThickness</span><span>="1"</span><span> Width</span><span>="100"</span><span> HorizontalAlignment</span><span>="Left"</span><span>
Title</span><span>="</span><span>{Binding Value, ElementName=slider}</span><span>"</span><span> myControls:MyAttachedProperty.SubTitle</span><span>="</span><span>{Binding Value, ElementName=slider}</span><span>"</span><span>/></span><span><</span><span>Slider </span><span>Name</span><span>="slider"</span><span> Width</span><span>="100"</span><span> Minimum</span><span>="0"</span><span> Maximum</span><span>="200"</span><span> IsThumbToolTipEnabled</span><span>="False"</span><span> HorizontalAlignment</span><span>="Left"</span><span>/></span><span></</span><span>StackPanel</span><span>></span><span></</span><span>Grid</span><span>></span><span></</span><span>Page</span><span>></span>
4、控件的继承关系的概述
Controls/Basic/Inherit.xaml
<span><</span><span>Page
</span><span>x:Class</span><span>="XamlDemo.Controls.Basic.Inherit"</span><span>
xmlns</span><span>="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span><span>
xmlns:x</span><span>="http://schemas.microsoft.com/winfx/2006/xaml"</span><span>
xmlns:local</span><span>="using:XamlDemo.Controls.Basic"</span><span>
xmlns:d</span><span>="http://schemas.microsoft.com/expression/blend/2008"</span><span>
xmlns:mc</span><span>="http://schemas.openxmlformats.org/markup-compatibility/2006"</span><span>
mc:Ignorable</span><span>="d"</span><span>></span><span><</span><span>Grid </span><span>Background</span><span>="Transparent"</span><span>></span><span><</span><span>StackPanel </span><span>Margin</span><span>="120 0 0 0"</span><span>></span><span><</span><span>TextBlock </span><span>Name</span><span>="lblMsg"</span><span> FontSize</span><span>="14.667"</span><span> LineHeight</span><span>="25"</span><span>></span><span><</span><span>Run</span><span>></span>继承关系: FrameworkElement -> UIElement -> DependencyObject<span></</span><span>Run</span><span>></span><span><</span><span>LineBreak </span><span>/></span><span><</span><span>Run</span><span>></span>DependencyObject - 提供对依赖属性的访问,以及获取此对象关联的 CoreDispatcher<span></</span><span>Run</span><span>></span><span><</span><span>LineBreak </span><span>/></span><span><</span><span>Run</span><span>></span>UIElement - 可视元素,键盘和鼠标输入等<span></</span><span>Run</span><span>></span><span><</span><span>LineBreak </span><span>/></span><span><</span><span>Run</span><span>></span>FrameworkElement - 框架元素,数据绑定,一些公共 API 等。例:Control, TextBlock, WebView 等继承自 FrameworkElement<span></</span><span>Run</span><span>></span><span><</span><span>LineBreak </span><span>/></span><span><</span><span>Run</span><span>></span>ContentControl - 其内包含有一个内容,继承自 Control。例:ScrollViewer, AppBar 等继承自 ContentControl<span></</span><span>Run</span><span>></span><span><</span><span>LineBreak </span><span>/></span><span><</span><span>Run</span><span>></span>ButtonBase - 按钮的基本功能,继承自 ContentControl。例:Button, RepeatButton 等继承自 ButtonBase<span></</span><span>Run</span><span>></span><span><</span><span>LineBreak </span><span>/></span><span><</span><span>Run</span><span>></span>ToggleButton - 可切换状态的按钮,继承自 ButtonBase。例:RadioButton, CheckBox 等继承自 ToggleButton<span></</span><span>Run</span><span>></span><span><</span><span>LineBreak </span><span>/></span><span><</span><span>Run</span><span>></span>RangeBase - 值在某一范围内,继承自 ButtonBase。例:ProgressBar, Slider, ScrollBar 等继承自 RangeBase<span></</span><span>Run</span><span>></span><span><</span><span>LineBreak </span><span>/></span><span><</span><span>Run</span><span>></span>ItemsControl - 用于呈现集合,继承自 Control<span></</span><span>Run</span><span>></span><span><</span><span>LineBreak </span><span>/></span><span><</span><span>Run</span><span>></span>Selector - 可选择集合中的某一项,继承自 ItemsControl。例:ComboBox, ListBox, FlipView, ListViewBase 等继承自 Selector<span></</span><span>Run</span><span>></span><span><</span><span>LineBreak </span><span>/></span><span><</span><span>Run</span><span>></span>ListViewBase - 继承自 ListViewBase 的控件有 GridView 和 ListView<span></</span><span>Run</span><span>></span><span><</span><span>LineBreak </span><span>/></span><span><</span><span>Run</span><span>></span>Panel - 一个容器,继承自 FrameworkElement。例:Grid, StackPanel, Canvas 等继承自 Panel<span></</span><span>Run</span><span>></span><span><</span><span>LineBreak </span><span>/></span><span><</span><span>Run</span><span>></span>如 ScrollBar, Thumb, RangeBase, ButtonBase, Selector, Popup 等这类基元控件在 Windows.UI.Xaml.Controls.Primitives 命名空间下<span></</span><span>Run</span><span>></span><span></</span><span>TextBlock</span><span>></span><span></</span><span>StackPanel</span><span>></span><span></</span><span>Grid</span><span>></span><span></</span><span>Page</span><span>></span>
5、路由事件和命中测试
Controls/Basic/RoutedEventDemo.xaml
<span><</span><span>Page
</span><span>x:Class</span><span>="XamlDemo.Controls.Basic.RoutedEventDemo"</span><span>
xmlns</span><span>="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span><span>
xmlns:x</span><span>="http://schemas.microsoft.com/winfx/2006/xaml"</span><span>
xmlns:local</span><span>="using:XamlDemo.Controls.Basic"</span><span>
xmlns:d</span><span>="http://schemas.microsoft.com/expression/blend/2008"</span><span>
xmlns:mc</span><span>="http://schemas.openxmlformats.org/markup-compatibility/2006"</span><span>
mc:Ignorable</span><span>="d"</span><span>></span><span><</span><span>Grid </span><span>Background</span><span>="Transparent"</span><span>></span><span><</span><span>StackPanel </span><span>Margin</span><span>="120 0 0 0"</span><span>></span><span><</span><span>Grid </span><span>HorizontalAlignment</span><span>="Left"</span><span> VerticalAlignment</span><span>="Top"</span><span>></span><span><!--</span><span>
演示事件冒泡:儿子传递事件给爸爸,爸爸传递事件给爷爷,这就是事件冒泡
</span><span>--></span><span><</span><span>Border </span><span>Name</span><span>="borderRed"</span><span> Background</span><span>="Red"</span><span> Width</span><span>="300"</span><span> Height</span><span>="300"</span><span>></span><span><</span><span>Border </span><span>Name</span><span>="borderGreen"</span><span> Background</span><span>="Green"</span><span> Width</span><span>="250"</span><span> Height</span><span>="250"</span><span> Tapped</span><span>="borderGreen_Tapped_1"</span><span>></span><span><</span><span>Border </span><span>Name</span><span>="borderBlue"</span><span> Background</span><span>="Blue"</span><span> Width</span><span>="200"</span><span> Height</span><span>="200"</span><span> Tapped</span><span>="borderBlue_Tapped_1"</span><span>></span><span><</span><span>Border </span><span>Name</span><span>="borderOrange"</span><span> Background</span><span>="Orange"</span><span> Width</span><span>="150"</span><span> Height</span><span>="150"</span><span> Tapped</span><span>="borderOrange_Tapped_1"</span><span>></span><span><!--</span><span>命中测试不可见,也就是说 borderPurple 和 borderYellow 均命中测试不可见</span><span>--></span><span><</span><span>Border </span><span>Name</span><span>="borderPurple"</span><span> Background</span><span>="Purple"</span><span> Width</span><span>="100"</span><span> Height</span><span>="100"</span><span> Tapped</span><span>="borderPurple_Tapped_1"</span><span> IsHitTestVisible</span><span>="False"</span><span>></span><span><</span><span>Border </span><span>Name</span><span>="borderYellow"</span><span> Background</span><span>="Yellow"</span><span> Width</span><span>="50"</span><span> Height</span><span>="50"</span><span> Tapped</span><span>="borderYellow_Tapped_1"</span><span>/></span><span></</span><span>Border</span><span>></span><span></</span><span>Border</span><span>></span><span></</span><span>Border</span><span>></span><span></</span><span>Border</span><span>></span><span></</span><span>Border</span><span>></span><span><!--</span><span>
像这样排列元素,是没有事件冒泡的,而只是前面的元素响应事件,后面的元素不会响应事件,也就是说同辈间没有事件冒泡的概念
IsHitTestVisible - 是否对命中测试可见
<Rectangle Name="rectangle1" Width="800" Height="400" Fill="Red" />
<Rectangle Name="rectangle2" Width="700" Height="350" Fill="Green" />
<Rectangle Name="rectangle3" Width="600" Height="300" Fill="Blue" />
<Rectangle Name="rectangle4" Width="500" Height="250" Fill="Orange" />
<Rectangle Name="rectangle5" Width="400" Height="200" Fill="Purple" />
</span><span>--></span><span></</span><span>Grid</span><span>></span><span><</span><span>TextBlock </span><span>Name</span><span>="lblMsg"</span><span> FontSize</span><span>="14.667"</span><span> Margin</span><span>="0 10 0 0"</span><span>/></span><span></</span><span>StackPanel</span><span>></span><span></</span><span>Grid</span><span>></span><span></</span><span>Page</span><span>></span>Controls/Basic/RoutedEventDemo.xaml.cs
<span>/*</span><span>
* 演示路由事件的冒泡和命中测试的可见性
*
* TappedRoutedEventArgs
* OriginalSource - 引发此路由事件的对象
* Handled - 是否将路由事件标记为已处理
* true - 不再冒泡
* false - 继续冒泡
*
* UIElement
* IsHitTestVisible - 是否对命中测试可见
</span><span>*/</span><span>using</span><span> System;
</span><span>using</span><span> Windows.UI.Xaml;
</span><span>using</span><span> Windows.UI.Xaml.Controls;
</span><span>using</span><span> Windows.UI.Xaml.Input;
</span><span>namespace</span><span> XamlDemo.Controls.Basic
{
</span><span>public</span><span>sealed</span><span>partial</span><span>class</span><span> RoutedEventDemo : Page
{
</span><span>public</span><span> RoutedEventDemo()
{
</span><span>this</span><span>.InitializeComponent();
</span><span>//</span><span> AddHandler() - 注册一个路由事件,注意最后一个参数:true 代表即使子辈 TappedRoutedEventArgs.Handled = true 也不会影响此元素事件的触发
</span><span>//</span><span> RemoveHandler() - 移除指定的路由事件</span>
borderRed.AddHandler(UIElement.TappedEvent, <span>new</span> TappedEventHandler(borderRed_Tapped_1), <span>true</span><span>);
}
</span><span>private</span><span>void</span> borderRed_Tapped_1(<span>object</span><span> sender, TappedRoutedEventArgs e)
{
lblMsg.Text </span>+= <span>"</span><span>borderRed tapped, originalSource: </span><span>"</span> + (e.OriginalSource <span>as</span><span> FrameworkElement).Name;
lblMsg.Text </span>+=<span> Environment.NewLine;
}
</span><span>private</span><span>void</span> borderGreen_Tapped_1(<span>object</span><span> sender, TappedRoutedEventArgs e)
{
lblMsg.Text </span>+= <span>"</span><span>borderGreen tapped, originalSource: </span><span>"</span> + (e.OriginalSource <span>as</span><span> FrameworkElement).Name;
lblMsg.Text </span>+=<span> Environment.NewLine;
}
</span><span>private</span><span>void</span> borderBlue_Tapped_1(<span>object</span><span> sender, TappedRoutedEventArgs e)
{
lblMsg.Text </span>+= <span>"</span><span>borderBlue tapped, originalSource: </span><span>"</span> + (e.OriginalSource <span>as</span><span> FrameworkElement).Name;
lblMsg.Text </span>+=<span> Environment.NewLine;
</span><span>//</span><span> 不会再冒泡,也就是说 borderGreen 无法响应 Tapped 事件,但是 borderRed 注册 Tapped 事件时 handledEventsToo = true,所以 borderRed 会响应 Tapped 事件</span>
e.Handled = <span>true</span><span>;
}
</span><span>private</span><span>void</span> borderOrange_Tapped_1(<span>object</span><span> sender, TappedRoutedEventArgs e)
{
lblMsg.Text </span>+= <span>"</span><span>borderOrange tapped, originalSource: </span><span>"</span> + (e.OriginalSource <span>as</span><span> FrameworkElement).Name;
lblMsg.Text </span>+=<span> Environment.NewLine;
}
</span><span>private</span><span>void</span> borderPurple_Tapped_1(<span>object</span><span> sender, TappedRoutedEventArgs e)
{
</span><span>//</span><span> 不会响应此事件,因为 borderPurple 的 IsHitTestVisible = false</span>
lblMsg.Text += <span>"</span><span>borderPurple tapped, originalSource: </span><span>"</span> + (e.OriginalSource <span>as</span><span> FrameworkElement).Name;
lblMsg.Text </span>+=<span> Environment.NewLine;
}
</span><span>private</span><span>void</span> borderYellow_Tapped_1(<span>object</span><span> sender, TappedRoutedEventArgs e)
{
</span><span>//</span><span> 不会响应此事件,因为 borderYellow 的爸爸 borderPurple 的 IsHitTestVisible = false</span>
lblMsg.Text += <span>"</span><span>borderYellow tapped, originalSource: </span><span>"</span> + (e.OriginalSource <span>as</span><span> FrameworkElement).Name;
lblMsg.Text </span>+=<span> Environment.NewLine;
}
}
}</span>
OK
[源码下载]
原文:http://www.cnblogs.com/lonelyxmas/p/3588060.html
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!