PDA

View Full Version : سوال: نحوه کار Circularpath



sinaone1
چهارشنبه 01 تیر 1390, 07:49 صبح
سلام دوستان حتما circularpath رو توی خیلی از اپلیکیشن ها دیدید یکیشم مثال PCGaming توی Expression blend هست فقط من زیاد از روش کارش سر در نمیارم و نمیدونم کداش چطوری کار میکنه ، البته منظور من کلا پدهایی هست که می تونیم خودمون طراحی کنیم و خوب Circular هم یکی از اونهاست ، از دوستان کسی هست که بتونه روش ساخت رو توضیح بده؟
ممنون

مهدی فرزاد
چهارشنبه 01 تیر 1390, 11:05 صبح
سلام

اگر منظور شما CircularPanel هست که توضیحش رو در زیر خواهم داد

(Path با Panel فرق میکنه شما میتونید با ابزار Pen در Blend هر نوع Path رو رسم کنید!)


در این نوع پنل ها که خصوصیات خودشون رو از Panel به ارث میبرن یک سری Property از نوع DependencyProperty درست شده که اطلاعاتی رو جهت طریقه نمایش و چیدمان آیتمهای قرار گرفته در پنل دریافت میکنن
کد های زیر کلا برا تعریف DependencyProperty هست ( در مثال شما )


public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register("Radius", typeof(double), typeof(CircularPanel), new PropertyMetadata(CircularPanel.RadiusChanged));
public static readonly DependencyProperty AngleItemProperty = DependencyProperty.Register("AngleItem", typeof(double), typeof(CircularPanel), new PropertyMetadata(CircularPanel.AngleItemChanged));
public static readonly DependencyProperty IsAnimatedProperty = DependencyProperty.Register("IsAnimated", typeof(bool), typeof(CircularPanel), new PropertyMetadata(CircularPanel.IsAnimatedChanged)) ;
public static readonly DependencyProperty AnimationDurationProperty = DependencyProperty.Register("AnimationDuration", typeof(int), typeof(CircularPanel), new PropertyMetadata(CircularPanel.AnimationDurationCh anged));
public static readonly DependencyProperty InitialAngleProperty = DependencyProperty.Register("InitialAngle", typeof(double), typeof(CircularPanel), new PropertyMetadata(CircularPanel.InitialAngleChanged ));
public static readonly DependencyProperty AlignProperty = DependencyProperty.Register("Align", typeof(AlignmentOptions), typeof(CircularPanel), new PropertyMetadata(CircularPanel.AlignChanged));

private static void RadiusChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ((CircularPanel)sender).Refresh(); }
private static void AngleItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ((CircularPanel)sender).Refresh(); }
private static void IsAnimatedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ((CircularPanel)sender).OnIsAnimatedChanged(e); }
private static void AnimationDurationChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ((CircularPanel)sender).Refresh(); }
private static void InitialAngleChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ((CircularPanel)sender).Refresh(); }
private static void AlignChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ((CircularPanel)sender).Refresh(); }

[Category("Circular Panel")]
public double Radius
{
get { return (double)this.GetValue(CircularPanel.RadiusProperty ); }
set { this.SetValue(CircularPanel.RadiusProperty, value); }
}

[Category("Circular Panel")]
public double AngleItem
{
get { return (double)this.GetValue(CircularPanel.AngleItemPrope rty); }
set { this.SetValue(CircularPanel.AngleItemProperty, value); }
}

[Category("Circular Panel")]
public bool IsAnimated
{
get { return (bool)this.GetValue(CircularPanel.IsAnimatedProper ty); }
set { this.SetValue(CircularPanel.IsAnimatedProperty, value); }
}

[Category("Circular Panel")]
public int AnimationDuration
{
get { return (int)this.GetValue(CircularPanel.AnimationDuration Property); }
set { this.SetValue(CircularPanel.AnimationDurationPrope rty, value); }
}

[Category("Circular Panel")]
public double InitialAngle
{
get { return (double)this.GetValue(CircularPanel.InitialAnglePr operty); }
set { this.SetValue(CircularPanel.InitialAngleProperty, value); }
}

[Category("Circular Panel")]
public AlignmentOptions Align
{
get { return (AlignmentOptions)this.GetValue(CircularPanel.Alig nProperty); }
set { this.SetValue(CircularPanel.AlignProperty, value); }
}
جهت کسب اطلاعات بیشتر در مورد این نوع خصوصیات لینک زیر رو ببینید
http://www.wpftutorial.net/DependencyProperties.html

مثلا با توجه به زاویه چرخشی که کاربر از طریق خصوصایت تعریف شده بهش میده میاد و هر آیتمی رو که در پنل قرار میگیره به همون میزان میچرخنونه
مثلا کد های زیر

foreach (FrameworkElement element in this.Children)
{
RotateTransform r = new RotateTransform();
double alignX = 0;
double alignY = 0;
switch (this.Align)
{
case AlignmentOptions.Left:
alignX = 0;
alignY = 0;
break;
case AlignmentOptions.Center:
alignX = element.DesiredSize.Width / 2;
alignY = element.DesiredSize.Height / 2;
break;
case AlignmentOptions.Right:
alignX = element.DesiredSize.Width;
alignY = element.DesiredSize.Height;
break;
}
r.CenterX = alignX;
r.CenterY = alignY;
r.Angle = (this.AngleItem * count++) - this.InitialAngle;
element.RenderTransform = r;
double x = this.Radius * Math.Cos(Math.PI * r.Angle / 180);
double y = this.Radius * Math.Sin(Math.PI * r.Angle / 180);

if (!(double.IsNaN(this.Width)) && !(double.IsNaN(this.Height)) && !(double.IsNaN(alignX)) && !(double.IsNaN(alignY)) && !(double.IsNaN(element.DesiredSize.Width)) && !(double.IsNaN(element.DesiredSize.Height)))
{
element.Arrange(new Rect(x + this.Width / 2 - alignX, y + this.Height / 2 - alignY, element.DesiredSize.Width, element.DesiredSize.Height));
}
}

برای استفاده از اون هم وقتی برنامه رو یک بار Build کنی به لیست کنترل هات اضافه میشه کافیه اونو توی فرمت بگذاری و چند تا کنترل دیگه مثلا Image یا TextBlock توش بگذاری و با تنظیم خصوصیات که داره ( همون هایی که در بالا تعریف شده ) مانند شکل زیر نتیجه رو ببینی
71455
اگر از اون به عنوان panel در Style مربوط به ListBox برای چیدمان listBoxItem استفاده کنی
<Style x:Key="MenuListBoxItemStyle" TargetType="ListBoxItem">
<Setter Property="Padding" Value="3"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="TabNavigation" Value="Local"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<PCGaming:CircularPanel Width="494" Height="494" Radius="90" Margin="-324,0,0,0" AngleItem="6">
میتونی این استایل رو به هر لیست باکسی بدی و نتیجه رو در چیدمان ببینی
برای بررسی طریقه استفاده از اون در استایل کنترل ها میتونی توی همون مثالی که گفتی در نرم افزار Blend مثال رو باز کنی و در تب Resources چند استایل هست که میتونی بررسیشون کنی
71456