استاد ، یه Control Template برای CheckBox نوشتم (شبیه checkbox در تنظیمات powerdvd) :
کد:
<ControlTemplate x:Key="checkBoxCustTemplate" TargetType="CheckBox">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="16"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="16" Height="16" CornerRadius="1" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1">
<Border.Child>
<Path Name="tickPath" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="1" Fill="{TemplateBinding BorderBrush}" StrokeStartLineCap="Triangle" StrokeEndLineCap="Triangle">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure StartPoint="1, 7">
<PathFigure.Segments>
<QuadraticBezierSegment Point1="3, 7" Point2="5, 9" />
<QuadraticBezierSegment Point1="8, 4" Point2="12, 2" />
</PathFigure.Segments>
</PathFigure>
<PathFigure StartPoint="1, 7">
<PathFigure.Segments>
<QuadraticBezierSegment Point1="3.2, 7.2" Point2="5, 11" />
<QuadraticBezierSegment Point1="8.2, 4.2" Point2="12, 2" />
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
</Border.Child>
</Border>
<ContentPresenter Grid.Column="1" Margin="4, 0, 0, 0"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="false">
<Trigger.Setters>
<Setter TargetName="tickPath" Property="Visibility" Value="Hidden"/>
</Trigger.Setters>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
وقتی روی قسمت Content اش کلیک میکنم ، مشکلی نیست .
ولی وقتی روی قسمت Border اش کلیک میکنم ، نمیدونم چرا گاها تیک اش عمل میکنه (تیک میزنه) و گاها عمل نمیکنه (تیک نمیزنه) !!
نمیدونم متوجه ی منظورم شدید یا نه .
واسه ی خودمم جای تعجب داره .
البته نمیدونم بخاطر این باشه که Grid ام را ستون بندی کردم یا نه .
اما اگه واسه ی ستون بندی اش باشه ، نمیشه این کد را با حفظ ستون بندی ، درست کرد؟
کلا مشکلش از کجاست؟
بله، ولی اون قسمتی که میگید رسم در شیِ VisualBrush انجام میشه درست نیست، در VisualBrush رسم انجام نمی دهید، چگونگی رسم رو تعریف می کنید.
خیلی ممنون استاد .
آها . اگه اشتباه نکنم ، زمانی میگیم رسم ای انجام شد که روی پنجره و کنترلی ، چیزی رسم بشه . در واقع در Device Context مربوط به اون پنجره ، رسم ای اتفاق بیفته . (هر چند مفهوم Device Context در کنترل ها را دقیق نمیدونم) .
اما وقتی شی Brush ای داریم ، این شی ، صرفا یه شی در حافظه هست . که صرفا شامل توصیفات اون رسم هست که وقتی از روی این توصیفات ، Render ای در Device Context مربوط به فلان کنترل ، صورت بگیره ، در اون زمان میگیم که رسم ای انجام شد . نه اینکه وقتی شی Brush ای داریم ، در شی Brush ، چیزی رسم شده باشه . چون شی Brush مون که رسم و رندر ای نداره .
درسته؟
چیزی که نگران Dispose شدنش باشند ندارند. وقتی یک کنترل فرضا TextBox میساختید با Dispose خود شیء TextBox که نابود نمیشد، null که نمیشد، شیء اش همچنان سر جاش بود.
چیزی که با Dispose نابود میشد اون منابعی بود که از جای دیگری مثل سیستم عامل گرفته شده بود، مثلا پنجره اش نابود میشد. اون TextBox یک کلاس NET. داشت اما اساسش یک پنجره و کلاس TextBox ویندوز بود که برای ساختنش از منابع ویندوز استفاده شده بود.
بله . میدونم .
قبلا زحمت توضیح اینها را کشیده بودین .
اما در WPF با یکسری اشیاء انتزاعی کار می کنید که ارتباط مستقیمی با منابع در دست سیستم عامل یا حتی DirectX ندارند. کنترل در WPF یک شیء کاملا انتزاعی است که نمایش و عملکرد اش مستقل از شیء ئه.
دقیقا متوجه نشدم .
منظورتون از اشیاء انتزاعی ، چیه؟ منظورتون از ارتباط غیرمستقیم چیه؟
خوب در winform هم ارتباط مستقیم ندارند . چون اول کلاس ها و کنترلهای .net را فراخونی میکنیم (مثلا Button را) . بعد توی اون کلاس ها ، از منابع و api های سیستم عامل استفاده میشه . پس در اونجا هم ارتباط مستقیمی با api های ویندوز نداریم .
حالا چه مستقیم یا غیر مستقیم ، بالاخره وقتی در wpf ، ارتباط غیر مستقیم هم باشه ، بالاخره از api های ویندوز استفاده شده و چون منابع unmanaged هستند ، بعد از اتمام استفاده ، باید dispose بشن دیگه . درسته؟
اگه آره ، پس dispose ای نداره که dispose کنیم .
حتی نخی که رسم کنترل رو انجام میده هم مستقل ئه. موقع ساختن یک کنترل در WPF منابعی که مدیریت اش نظارت برنامه نویس رو بخواد دریافت نمی کنه که نگران آزاد شدنش باشه.
منظورتون اینه که مثلا توابع رسم اش در نخ مجزایی هست اما موقعی که میخوان رسم ای انجام بدن ، در نخ اصلی نرم افزار انجام میدن دیگه؟ مثل قضیه ی متد Invoke در winform . درسته؟
اگه درست نیست ، مگه امکان پذیره؟ یعنی ما هم میتونیم در نخ مجزایی در wpf ، رسم مون را انجام بدیم؟!!
البته من درباره ی Freezable Object در wpf یه چیزهایی خوندم که اونم اگه قابلیت freez این اشیاء ها را فعال کنیم (که باعث میشه اعضاش فقط قابل خوندن بشن و دیگه نمیشه توی اعضاش چیزی را نوشت) ، میتونیم توی نخ مجزا با این اشیاء کار کنیم . و همچنین افزایش کارایی خواهند داشت . اما خیلی از کنترل ها که Freezable Object نیستند .
کلا این مورد را متوجه نشدم که قضیه اش چیه؟
دو تا مورد متفاوت هستند. DrawToBitmap برای یک تصویر Device Context یا همون DC دریافت می کنه و کنترل رو بجای رسم عادی که در DC خود کنترل انجام میشد اینبار در DC اون تصویر رسم می کنه.
اون چیزی که DrawToBitmap به عنوان ورودی میخواد تصویر ئه.
اما ImageSource که خود تصویر نیست، تعریف منبعی است که تصویر رو میشه از طریق اون ایجاد کرد.
حالا منظورم ImageSource یا فرزندش BitmapImage بود .