سئوالات و مباحث WPF

the_king

مدیرکل انجمن
خیلی ممنون استاد .
استاد ، پیگیر مطلب Routed Event دیگه نشدم . وقتی توی لیست اینتلیسنس نمیاره ، دیگه حداقل یاد گرفتنش در حال حاضر ، فایده نداره . حالا در آینده و نسخه های بعدی ، هر وقت توی لیست اینتلیسنس آورد ، ان شاء ا... بررسی میکنم .
میل خودتونه اما Intellisense مشکلی با Routed Event نداره و نشونش میده، ولی منطق مشخصی داره. شما کلاس Button رو ببینید، رخداد Click نداره :
click.png
شما می خواهید Button.Click ای رو بنویسید که جزئی از ButtonBase ئه، نه Button. که Intellisense هم زیر بار خواسته شما نمیره. اگر می نوشتید ButtonBase.Click بدون مشکل Intellisense نشونش میداد.

استاد ، میگم من لینک زیر را کلا خوندم :

XAML overview - WPF

البته میانه هاش ، مطالب دیگه هم خوندم مثل Style & Template In Wpf و Geometry را تقریبا کامل خوندم و همچنین چندین تاپیک دیگه را بصورت سطحی نگاه کردم .
حالا میگم برای ادامه ، چه مطالبی نیازه بخونم تا با کلیات wpf آشنا بشم؟ (منظورم موارد اصلی هستن که با کلیات کار آشنا بشم) . تاپیک زیر نیازه هست . درسته؟ :

XAML Syntax In Detail - WPF

باز چه مواردی نیازه؟
XAML overview کلیات XAML ئه، نه WPF. کلیات WPF درXAML overview - WPF ئه که خودش چندین لینک overview داخلش هست که همه شون رو هم شامل نمیشه.
هر چیزی که در XAML overview نوشته کلیات XAML ئه و هر چی در XAML Syntax In Detail نوشته جزئیات XAML ئه.
هر تاپیک مرتبط با WPF که عنوان overview داره کلیات ئه، مثلا :
Data Templating Overview - WPF
Shapes and basic drawing overview - WPF
Focus Overview - WPF
Drag and Drop Overview - WPF
و ...
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
میل خودتونه اما Intellisense مشکلی با Routed Event نداره و نشونش میده، ولی منطق مشخصی داره. شما کلاس Button رو ببینید، رخداد Click نداره :
مشاهده پیوست 113452
شما می خواهید Button.Click ای رو بنویسید که جزئی از ButtonBase ئه، نه Button. که Intellisense هم زیر بار خواسته شما نمیره. اگر می نوشتید ButtonBase.Click بدون مشکل Intellisense نشونش میداد.

خیلی ممنون استاد .
آها ، مثل قضیه ی شی گرایی نیست که مثلا اگه اعضای فرزندش (مثل button) را نوشتیم ، اعضای کلاس پدرش (که ButtonBase هست) را بیاره؟
کد زیر را نوشتم :

کد:
                <Button HorizontalAlignment="Left" VerticalAlignment="Top" Margin="500, 200, 0 , 0" Width="500" Height="300" >
                    <Button.Content>
                      
                        <TabControl ButtonBase.Click="TabItem_Click" Style="{StaticResource SimpleTabControl }" HorizontalAlignment="Left" Height="155" Margin="0,0,0,0" VerticalAlignment="Top" Width="400">
                            <TabItem Header="TabItem">
                                <Grid Background="#FFE5E5E5">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="89*"/>
                                        <ColumnDefinition Width="16*"/>
                                        <ColumnDefinition Width="289*"/>
                                    </Grid.ColumnDefinitions>
                                    <Button Content="Button" HorizontalAlignment="Left" Height="39" Margin="153.25,49,0,0" VerticalAlignment="Top" Width="98" Grid.Column="2"/>
                                    <CheckBox Content="CheckBox" HorizontalAlignment="Left" Height="19" Margin="15.25,49,0,0" VerticalAlignment="Top" Width="112" Grid.Column="2"/>
                                    <Label Content="abcdefg" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="20, 20,0,0"/>
                                </Grid>
                            </TabItem>
                            <TabItem Header="TabItem">
                                <Grid Background="#FFE5E5E5">
                                    <ComboBox HorizontalAlignment="Left" Height="22" Margin="152,60,0,0" VerticalAlignment="Top" Width="132"/>
                                </Grid>
                            </TabItem>
                        </TabControl>
                      
                    </Button.Content>
                </Button>

و در زیر مجموعه ی (فرزندان از لحاظ کدهای xml) اون TabControl ، هر کنترلی که از نوع ButtonBase یا فرزندانِ ButtonBase (از لحاظ کدهای سی شارپ) بودن (یعنی کنترل های Button و CheckBox در کد بالا) ، به رویداد TabItem_Click متصل شدن و اون کنترل هایی هم که فرزند ButtonBase نبودن (مثل Label) ، متصل نشدن .
اما کنترل والد TabControl (که کنترل Button هست) ، این رویداد را اجرا نمیکنه .

اما اون قضیه ای که قبلا درباره ی مسیر گفته بودین (که به سمت پایین (فرزندان) یا بالا (والد)) طی میشه ، الان فقط به سمت پایین که همون فرزندان هستند ، طی میشه؟
به سمت بالا که کنترل های والد هستند ، طی نمیشه و کاری نداره؟ پس در اون لینک (که در پست 154 لینک دادم و در پست 159 ، قضیه ی مسیر و اون بانک را مثال زدین) پس چرا قضیه ی مسیر به سمت بالا و بصورت حباب را هم میگفت؟

و اینکه استاد ، چرا در کد بالا ، کنترل TabControl ، نسبت به گوشه های کنترل والدش که Button هست ، فاصله داره؟
Margin ئه مربوط به TabControl که کلا 0 هست . باید چی کار کنم (بدون مقدار دهی کردن پروپرتی جدیدی در TabControl) تا TabControl ام در گوشه ی بالا سمت چپ کنترل Button قرار بگیره؟

XAML overview کلیات XAML ئه، نه WPF. کلیات WPF درXAML overview - WPF ئه که خودش چندین لینک overview داخلش هست که همه شون رو هم شامل نمیشه.
هر چیزی که در XAML overview نوشته کلیات XAML ئه و هر چی در XAML Syntax In Detail نوشته جزئیات XAML ئه.
هر تاپیک مرتبط با WPF که عنوان overview داره کلیات ئه، مثلا :
Data Templating Overview - WPF
Shapes and basic drawing overview - WPF
Focus Overview - WPF
Drag and Drop Overview - WPF
و ...

خیلی ممنون استاد .
من همین کلیات را بدونم بس مه دیگه؟ درسته؟ (بجز اون XAML Syntax In Detail) .
جزئیات که خیلی همیشه وجود داره و نیاز به پرداختن برای وقتی که میخوایم بصورت کلی wpf را یاد بگیریم ، نیست . درست میگم؟
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
آها ، مثل قضیه ی شی گرایی نیست که مثلا اگه اعضای فرزندش (مثل button) را نوشتیم ، اعضای کلاس پدرش (که ButtonBase هست) را بیاره؟
کد زیر را نوشتم :

کد:
                <Button HorizontalAlignment="Left" VerticalAlignment="Top" Margin="500, 200, 0 , 0" Width="500" Height="300" >
                    <Button.Content>
                     
                        <TabControl ButtonBase.Click="TabItem_Click" Style="{StaticResource SimpleTabControl }" HorizontalAlignment="Left" Height="155" Margin="0,0,0,0" VerticalAlignment="Top" Width="400">
                            <TabItem Header="TabItem">
                                <Grid Background="#FFE5E5E5">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="89*"/>
                                        <ColumnDefinition Width="16*"/>
                                        <ColumnDefinition Width="289*"/>
                                    </Grid.ColumnDefinitions>
                                    <Button Content="Button" HorizontalAlignment="Left" Height="39" Margin="153.25,49,0,0" VerticalAlignment="Top" Width="98" Grid.Column="2"/>
                                    <CheckBox Content="CheckBox" HorizontalAlignment="Left" Height="19" Margin="15.25,49,0,0" VerticalAlignment="Top" Width="112" Grid.Column="2"/>
                                    <Label Content="abcdefg" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="20, 20,0,0"/>
                                </Grid>
                            </TabItem>
                            <TabItem Header="TabItem">
                                <Grid Background="#FFE5E5E5">
                                    <ComboBox HorizontalAlignment="Left" Height="22" Margin="152,60,0,0" VerticalAlignment="Top" Width="132"/>
                                </Grid>
                            </TabItem>
                        </TabControl>
                     
                    </Button.Content>
                </Button>

و در زیر مجموعه ی (فرزندان از لحاظ کدهای xml) اون TabControl ، هر کنترلی که از نوع ButtonBase یا فرزندانِ ButtonBase (از لحاظ کدهای سی شارپ) بودن (یعنی کنترل های Button و CheckBox در کد بالا) ، به رویداد TabItem_Click متصل شدن و اون کنترل هایی هم که فرزند ButtonBase نبودن (مثل Label) ، متصل نشدن .
اما کنترل والد TabControl (که کنترل Button هست) ، این رویداد را اجرا نمیکنه .

اما اون قضیه ای که قبلا درباره ی مسیر گفته بودین (که به سمت پایین (فرزندان) یا بالا (والد)) طی میشه ، الان فقط به سمت پایین که همون فرزندان هستند ، طی میشه؟
به سمت پایین نیست، به سمت بالا است، Bubble ئه. کلیک در دکمه رخ داده و به سمت بالا (ریشه) حرکت کرده تا رسیده به TabControl و به مقصودش رسیده.

به سمت بالا که کنترل های والد هستند ، طی نمیشه و کاری نداره؟ پس در اون لینک (که در پست 154 لینک دادم و در پست 159 ، قضیه ی مسیر و اون بانک را مثال زدین) پس چرا قضیه ی مسیر به سمت بالا و بصورت حباب را هم میگفت؟
به سمت بالا یا Bubble به این مفهومه که در اون دکمه Button که در اولین سطر نوشته اید کلیک رخ بده و بعد بره به سمت Window تا ببینه برای این کلیک باید چه چیزی رو اجرا کنه. این میشه به سمت بالا. دیگه اگه به سمت بالا باشه اون ButtonBase.Click رو نمی بینه چون اون ButtonBase.Click در مسیر به سمت بالا دیده نمیشه.
رخداد های مسیریابی شده سه نوع متفاوت هستند، رخدادی مثل Click استراتژی Bubble داره، رخدادی مثل PreviewDrop استراتژی Tunnel داره و رخدادی مثل ToolTipOpening استراتژی Direct داره. طبعا توقع نداریم که رخدادی که استراتژی Bubble داره در فرزندش دنبال کاری که باید بکنه بگرده.
RoutingStrategy Enum (System.Windows)

و اینکه استاد ، چرا در کد بالا ، کنترل TabControl ، نسبت به گوشه های کنترل والدش که Button هست ، فاصله داره؟
Margin ئه مربوط به TabControl که کلا 0 هست . باید چی کار کنم (بدون مقدار دهی کردن پروپرتی جدیدی در TabControl) تا TabControl ام در گوشه ی بالا سمت چپ کنترل Button قرار بگیره؟
شما یک Content دادید که میگید سمت چپ و بالا قرار بگیره و بچسبه به گوشه کادر، اما به گوشه کدوم کادر بچسبه؟ به گوشه کادر ContentPresenter ئه، نه خود Button. اون Button ئه Template داره و در Template اش گفته ContentPresenter ئه وسط قرار بگیره. شما هر چقدر هم که Content ئه رو به گوشه نزدیک کنید خود ContentPresenter که Content داخلش قرار داره وسط Button قرار میگیره و از گوشه Button فاصله داره.
باید Template ای بسازید که ContentPresenter وسط نباشه.

خیلی ممنون استاد .
من همین کلیات را بدونم بس مه دیگه؟ درسته؟ (بجز اون XAML Syntax In Detail) .
جزئیات که خیلی همیشه وجود داره و نیاز به پرداختن برای وقتی که میخوایم بصورت کلی wpf را یاد بگیریم ، نیست . درست میگم؟
بس برای چه منظوری؟ برای برنامه نویسی؟ فکر نکنم فقط با دانستن کلیات بشه همچین کاری کرد.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلی ممنون استاد .
مبحث Routed Events را برای آینده میخوام بذارم . انگار هم اهمیت اش نسبت به مباحث دیگه پایین تر هه و هم زیاده و هم اندکی در مباحث پیشرفته تر ، سخت تر میشه (هر چند بصورت اجمالی ، آسون هه) .

الان دارم مبحث Binding را در مقاله ی زیر پیگیری میکنم :

Data binding overview - WPF

یه چیز را قشنگ متوجه نشدم . اون هم تفاوت پروپرتی Resource و RelativeResource در Binding هست . Resource رو انگار متوجه شدم اما کاربرد RelativeResource رو متوجه نشدم. کاربرد و تفاوت شون در کجاست؟
البته در حد تئوری یه چیزهایی از RelativeResource متوجه شدم . مثلا اینکه در style و template ها یا وقتی که یه پروپرتی از یه شی را به یه پروپرتیِ دیگه از همون شی بخوایم متصل کنیم اما عملا برام واضح نیست .
میشه بجای RelativeResource ، فقط از Resource استفاده کنیم؟
بعد اینکه تفاوت Binding و TemplateBinding هم چیه؟ آیا میشه بجای TemplateBinding ، از Binding استفاده کرد؟


بعد اینکه چیزهایی که تا به اینجا متوجه شدم (تا قبل از بخش "Specifying the path to the value") و چک کنین ببینین درست میگم یا نه ، اینه که Binding ، از 4 بخش تشکیل شده . یععنی 4 چیز را برای استفاده از Binding باید مشخص کنیم :

basic-data-binding-diagram.png


1) Binding Target که شی ای هست که قراره عضوی از شیِ Source به پروپرتی ای از این کلاس متصل بشه . این Binding Target ، باید از نوع Dependency Object (یا فرزندان این کلاس مثل تمام اشیاء کلاس Visual) باشه . مثلا اگه قراره پروپرتیِ TextBox.Text را به چیزی Bind کنیم ، شی TextBox ، همون Binding Target مون هست . Binding Target ، کلا باید از نوع کنترل و کلا شی بصری باشه . یعنی اعضای غیر بصری را نمیشه Bind کرد.

2) Dependency Property که پروپرتی ای که عضو اون کلاس Dependency Object قبلی بود هست و در واقع پروپرتی ای هست که قراره عضوی از شیِ Source بهش متصل بشه . و همچنین پروپرتی ای باید باشه که از نوع Dependency Property باشه . در واقع ، این پروپرتی ، باید اتریباتسِ System.ComponentModel.Bindable را داشته باشه تا قابل Bind کردن باشه . اغلب پروپرتی های کلاس UIElement و فرزندانشون ، این طورن.
مثلا اگه قراره پروپرتیِ TextBox.Text را به چیزی Bind کنیم ، پروپرتیِ Text ، همون Dependency Property مون هست .
فقط اعضای پروپرتی ها میتونن Dependency Property بشن؟ مثلا فیلدها یا اعضای خاصی از آرایه ها را نمیتونیم Bind کنیم؟

3) Binding Source که شی ای که قراره عضوی ازش ، به عضوی از Binding Target مون متصل بشه . این شی ، محدود به شی بصری و کنترل نیست و هر نوع شی ای که شامل داده ای (پروپرتی یا آرایه) باشه را شامل میشه .

4) Path که همون پروپرتی یا آرایه یا فیلد یا کلا عضوی از شی Binding Source هست و قراره منبع داده ی متصل شده به شی پروپرتیِ Dependency Property که در مرحله ی 2 صحبت کردیم ، بشه .

قضیه ی Binding را هم که قبلا توضیح دادین .
حالا Mode های تک راه و دو راه و یک راه به منبع و ... داریم که مشخص هه چی هستن و الحمدلله بلدم .

خیلی ممنون استاد .
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
مبحث Routed Events را برای آینده میخوام بذارم . انگار هم اهمیت اش نسبت به مباحث دیگه پایین تر هه و هم زیاده و هم اندکی در مباحث پیشرفته تر ، سخت تر میشه (هر چند بصورت اجمالی ، آسون هه) .

الان دارم مبحث Binding را در مقاله ی زیر پیگیری میکنم :

Data binding overview - WPF

یه چیز را قشنگ متوجه نشدم . اون هم تفاوت پروپرتی Resource و RelativeResource در Binding هست . Resource رو انگار متوجه شدم اما کاربرد RelativeResource رو متوجه نشدم. کاربرد و تفاوت شون در کجاست؟
البته در حد تئوری یه چیزهایی از RelativeResource متوجه شدم . مثلا اینکه در style و template ها یا وقتی که یه پروپرتی از یه شی را به یه پروپرتیِ دیگه از همون شی بخوایم متصل کنیم اما عملا برام واضح نیست .
میشه بجای RelativeResource ، فقط از Resource استفاده کنیم؟
فکر کنم RelativeResource رو خودتون اختراع کردید، نمیدونم چیه. اگر منظورتون RelativeSource ئه، خیر. نمیشه جای هم استفاده کرد. یک وقت هست که منبع یک مورد مشخصی است، مثلا در Resources یک مدخل مشخصی رو تعریف کرده اید که میگید منبع این مدخل ئه. اما یک وقت هست که منبع اون چیزی است که دارید برایش توصیف می نویسید، اسمش رو نمی دونید، نسبی ئه. مثلا دارید برای TextBox ها Style توصیف می کنید، منبع تون اون TextBox ای است که دارید برایش Style می نویسید، ما که نمیدونیم اون TextBox ئه که Style برایش بکار میره چی میشه، این TextBox ئه یک RelativeSource ئه. نسبت به چیزی که توصیف میشه سنجیده میشه.

بعد اینکه تفاوت Binding و TemplateBinding هم چیه؟ آیا میشه بجای TemplateBinding ، از Binding استفاده کرد؟
TemplateBinding یک نوع Binding ئه که در ControlTemplate بکار میره، ساخته شده برای اتصال بین مشخصه های کنترل. بله، میشه ولی نه به سادگی TemplateBinding.
مثلا در TemplateBinding به سادگی می نوشتیم :
کد:
Margin="{TemplateBinding Padding}"
ولی برای Binding مجبوریم مشخص کنیم که منبع Template ئه نیست، کنترلی است که Template ئه برایش بکار میره :
کد:
Margin="{Binding Padding, RelativeSource={RelativeSource TemplatedParent}}"
بعد اینکه چیزهایی که تا به اینجا متوجه شدم (تا قبل از بخش "Specifying the path to the value") و چک کنین ببینین درست میگم یا نه ، اینه که Binding ، از 4 بخش تشکیل شده . یععنی 4 چیز را برای استفاده از Binding باید مشخص کنیم :

basic-data-binding-diagram.png


1) Binding Target که شی ای هست که قراره عضوی از شیِ Source به پروپرتی ای از این کلاس متصل بشه . این Binding Target ، باید از نوع Dependency Object (یا فرزندان این کلاس مثل تمام اشیاء کلاس Visual) باشه . مثلا اگه قراره پروپرتیِ TextBox.Text را به چیزی Bind کنیم ، شی TextBox ، همون Binding Target مون هست .
بله
Binding Target ، کلا باید از نوع کنترل و کلا شی بصری باشه . یعنی اعضای غیر بصری را نمیشه Bind کرد.
نمیدونم چطوری این نتیجه رو گرفتید، مثلا به نظرتون Trigger کنترل یا شیء بصری است؟

2) Dependency Property که پروپرتی ای که عضو اون کلاس Dependency Object قبلی بود هست و در واقع پروپرتی ای هست که قراره عضوی از شیِ Source بهش متصل بشه.
بله.

و همچنین پروپرتی ای باید باشه که از نوع Dependency Property باشه . در واقع ، این پروپرتی ، باید اتریباتسِ System.ComponentModel.Bindable را داشته باشه تا قابل Bind کردن باشه . اغلب پروپرتی های کلاس UIElement و فرزندانشون ، این طورن.
خیر. مثلا شما Width یک المنت رو به Width یک المنت دیگه متصل می کنید، Width ها هم که صفت Bindable ندارند.
کد:
Width="{Binding ElementName=MyElementName, Path=Width, Mode=TwoWay}"
توضیحات Remarks رو بخونید :
BindableAttribute Class (System.ComponentModel)

فقط اعضای پروپرتی ها میتونن Dependency Property بشن؟ مثلا فیلدها یا اعضای خاصی از آرایه ها را نمیتونیم Bind کنیم؟
XAML به شما اجازه میده مشخصه و رخداد رو توصیف کنید، نه فیلد یا چیز دیگری. برای دسترسی XAML فرضا به مشخصه کلاس هایی مثل DependencyProperty وجود داره، همینطوری XAML به مشخصه شیء دسترسی نداره. XAML کد زبان #C نیست که مستقیم به شی دسترسی داشته باشه و بخواد مقداری داخل فیلد یا عضو فلان آرایه قرار بده.

3) Binding Source که شی ای که قراره عضوی ازش ، به عضوی از Binding Target مون متصل بشه . این شی ، محدود به شی بصری و کنترل نیست و هر نوع شی ای که شامل داده ای (پروپرتی یا آرایه) باشه را شامل میشه .
بحث شی بصری و غیر بصری نیست.

4) Path که همون پروپرتی یا آرایه یا فیلد یا کلا عضوی از شی Binding Source هست و قراره منبع داده ی متصل شده به شی پروپرتیِ Dependency Property که در مرحله ی 2 صحبت کردیم ، بشه .
بله.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلی ممنون استاد . :rose:
استاد ، MultiBinding دقیقا در کجا کاربرد داره؟
الان در لینک زیر :

Binding.Source Property (System.Windows.Data)

و در مثالی که گفت :

کد:
<ComboBox.IsEnabled>
    <MultiBinding Converter="{StaticResource specialFeaturesConverter}">
        <Binding Path="CurrentUser.Rating"
          Source="{x:Static Application.Current}"/>
        <Binding Path="CurrentUser.MemberSince"
    Source="{x:Static Application.Current}"/>
    </MultiBinding>
</ComboBox.IsEnabled>

اولا دستور x:Static ، یک markup هست که زمانی که میخوایم یک عضو استاتیک را فراخونی کنیم ، مورد استفاده قرار میگیره دیگه . درسته؟

دوما در Source هر دو ، میگه Application.Current . این پروپرتی هم که کلاس Application را برمیگردونه . حالا وقتی در Path در Binding اولی ، مقدار "CurrentUser.Rating" را میذاره ، یعنی کلاس Application ، باید عضوی بنام CurrentUser داشته باشه و شی ای که این عضوی که برمیگردونه (هر چی که باشه) ، باید عضوی بنام Rating داشته باشه . مگه این طور نیست؟
خوب الان کلاس Application که عضوی بنام CurrentUser نداره . پس این Path که در بالا مقدار داد ، چه آدرسی هه؟ همینطور Path در دومین Binding ؟

سوما ، این الان برای ComboBox.IsEnabled ، این MultiBinding را بکار برد که خودِ MultiBinding شامل آرایه یا مجموعه ای از Binding ها میتونه باشه .
خوب الان 2 تا Binding ای که در MultiBinding برای ComboBox.IsEnabled (که فقط یک مقدار بولین را میگیره) ، به چه معناست؟
الان مثلا اگه Binding ئه اول (که مقدار Path اش CurrentUser.Rating هست) و فرض کنیم مقدارش true باشه و همچنین فرض کنیم که اگه Binding ئه دوم (که مقدار Path اش CurrentUser.MemberSince هست) و فرض کنیم مقدارش false باشه ، در این شرایط ، مقدار ComboBox.IsEnabled ، چی میشه؟ مقدار true میشه یا false میشه؟

چهارم اینکه مقدار MultiBinding.Mode در MultiBinding در مثال بالا ، OneWayToSource هست؟ اگه این طور باشه ، میشه گفت کارایی داره چون مسیر حرکت ، از target به سمت source هست .

---------------------------------------------------------

برای RelativeSource و همچنین کلا توضیحات پست قبلی تون هم خیلی ممنون .
لینک زیر هم مثال ها و توضیحات خوبی در این باره زد :

RelativeSources in WPF
 

the_king

مدیرکل انجمن
خیلی ممنون استاد . :rose:
استاد ، MultiBinding دقیقا در کجا کاربرد داره؟
وقتی مقدار یک چیزی باید بر اساس تغییرات مقدار چند تا چیز تغییر کنه یا برعکس. مقدارش بر اساس ترکیبی از چند مقدار بدست بیاد.
اولا دستور x:Static ، یک markup هست که زمانی که میخوایم یک عضو استاتیک را فراخونی کنیم ، مورد استفاده قرار میگیره دیگه . درسته؟
بله.
دوما در Source هر دو ، میگه Application.Current . این پروپرتی هم که کلاس Application را برمیگردونه . حالا وقتی در Path در Binding اولی ، مقدار "CurrentUser.Rating" را میذاره ، یعنی کلاس Application ،
باید عضوی بنام CurrentUser داشته باشه و شی ای که این عضوی که برمیگردونه (هر چی که باشه) ، باید عضوی بنام Rating داشته باشه . مگه این طور نیست؟
خوب الان کلاس Application که عضوی بنام CurrentUser نداره . پس این Path که در بالا مقدار داد ، چه آدرسی هه؟ همینطور Path در دومین Binding ؟
کلاس Application رو بر می گردونه، بله. اما شما کد اون پروژه رو دارید؟ روی چه کدی دارید تفسیر می کنید؟ کد مثال رو که ندیدید.
microsoft/WPF-Samples

سوما ، این الان برای ComboBox.IsEnabled ، این MultiBinding را بکار برد که خودِ MultiBinding شامل آرایه یا مجموعه ای از Binding ها میتونه باشه .
خوب الان 2 تا Binding ای که در MultiBinding برای ComboBox.IsEnabled (که فقط یک مقدار بولین را میگیره) ، به چه معناست؟
به این معنا است که مقدار ComboBox.IsEnabled بر اساس مقدار دو تا مورد تعیین میشه که در Converter مورد نظر تصمیم میگیره که true برگردونه یا false

الان مثلا اگه Binding ئه اول (که مقدار Path اش CurrentUser.Rating هست) و فرض کنیم مقدارش true باشه و همچنین فرض کنیم که اگه Binding ئه دوم (که مقدار Path اش CurrentUser.MemberSince هست) و فرض کنیم مقدارش false باشه ، در این شرایط ، مقدار ComboBox.IsEnabled ، چی میشه؟ مقدار true میشه یا false میشه؟
از من نپرسید، کد متد Convert در کلاس SpecialFeaturesConverter اون پروژه رو ببینید تا بفهمید true میشه یا false

چهارم اینکه مقدار MultiBinding.Mode در MultiBinding در مثال بالا ، OneWayToSource هست؟ اگه این طور باشه ، میشه گفت کارایی داره چون مسیر حرکت ، از target به سمت source هست .
بله، پیشفرض یکطرفه است، مگر در بعضی مشخصه ها که صریحا دو طرفه تعریف شده باشه، مثل Text
به کارایی ربطی نداره، IMultiValueConverter ها ConvertBack دارند، ممکنه بر اساس مقدار اون IsEnabled بخواد مقدار چند تا مشخصه رو تعیین کنه، یعنی از یک مقدار به چند مقدار برسه، ایرادی در اینکار نیست.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
کلاس Application رو بر می گردونه، بله. اما شما کد اون پروژه رو دارید؟ روی چه کدی دارید تفسیر می کنید؟ کد مثال رو که ندیدید.
microsoft/WPF-Samples

خیلی ممنون استاد . درباره ی جواب بقیه ی بخش ها هم خیلی ممنون .

خوب این لینکی که دادید ، کلاس App هست که از کلاس Application ارث بری میکنه .
یعنی میشه مثلا یک کلاس پدر (کلاس پدر که میگم ، منظورم از لحاظ کدهای سی شارپ هست) را در Source بدیم اما اعضای کلاس فرزند را در پروپرتی Path اش (در کد xaml) مشخص کنیم ؟ (برخلاف کدهای سی شارپ بصورت استاندارد) .


ضمن اینکه استاد ، شما مثلا از کجا متوجه شدین که اون کد xml ای که در اون لینک دادم ، از کلاس App که لینک دادین ، استفاده میکنه؟
و همچنین نحوه ی جستجوی مطالب تون توی اینترنت ، برام خیلی تحسین برانگیزه . من چی کار کنم و چه علوماتی باید داشته باشم تا بتونم مثل شما مطالبی که میخوام را جستجو کنم ؟
الان مثلا من نمیدونستم که اون کد ، درباره ی کلاس App ای که دادین ، صحبت میکنه (توی خود همون صفحه ی Binding.Source Property هم چیزی از این قضیه نگفت) .
غیر از این ، خیلی از اوقات دیگه هم هست که شما مطالبی پیدا میکنین که حتی من سرنخی ازش نمیتونم پیدا کنم تا چه برسه به اون مطلب اصلی اش را بخوام جستجو کنم.

خیلی ممنون .
 

the_king

مدیرکل انجمن
خوب این لینکی که دادید ، کلاس App هست که از کلاس Application ارث بری میکنه .
یعنی میشه مثلا یک کلاس پدر (کلاس پدر که میگم ، منظورم از لحاظ کدهای سی شارپ هست) را در Source بدیم اما اعضای کلاس فرزند را در پروپرتی Path اش (در کد xaml) مشخص کنیم ؟ (برخلاف کدهای سی شارپ بصورت استاندارد) .
به این مساله توجه کنید که در Source کلاس Application رو ندادید، یک شیء رو دادید که نوع داده اش سازگار و وارث Application ئه ولی خود کلاس Application نیست. شیء از کلاس App که وارث Application بود رو دادید. چرا؟ همانطور که در xmlns:local فضای نام پروژه رو مشخص کرده اید، XAML ئه داره در فضای نام پروژه شما تفسیر میشه و اون Application.Current در همین فضای نام اجرا میشه و برای همین یک شیء از کلاس App رو برمی گردونه، با نوع Application سازگار هست و Application محسوب میشه ولی نوع داده اش App ئه.

ضمن اینکه استاد ، شما مثلا از کجا متوجه شدین که اون کد xml ای که در اون لینک دادم ، از کلاس App که لینک دادین ، استفاده میکنه؟
زیر مثال نوشته بود که For the full example, see Data Binding Demo و لینک اش دیگه مثل سابق به مسیر مناسب هدایت نمیشد. در گوگل دنبال specialFeaturesConverter گشتم و پیدا شد.

و همچنین نحوه ی جستجوی مطالب تون توی اینترنت ، برام خیلی تحسین برانگیزه . من چی کار کنم و چه علوماتی باید داشته باشم تا بتونم مثل شما مطالبی که میخوام را جستجو کنم ؟
الان مثلا من نمیدونستم که اون کد ، درباره ی کلاس App ای که دادین ، صحبت میکنه (توی خود همون صفحه ی Binding.Source Property هم چیزی از این قضیه نگفت) .
غیر از این ، خیلی از اوقات دیگه هم هست که شما مطالبی پیدا میکنین که حتی من سرنخی ازش نمیتونم پیدا کنم تا چه برسه به اون مطلب اصلی اش را بخوام جستجو کنم.
فوت کوزه گری خاصی نداره، صرفا حاصل تجربه است و کمی هم عادت به تند خوانی. وقتی در یک موردی تجربه تون زیاد بشه کارهای مشابه اش رو به سادگی و به سرعت انجام می دهید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
به این مساله توجه کنید که در Source کلاس Application رو ندادید، یک شیء رو دادید که نوع داده اش سازگار و وارث Application ئه ولی خود کلاس Application نیست. شیء از کلاس App که وارث Application بود رو دادید. چرا؟ همانطور که در xmlns:local فضای نام پروژه رو مشخص کرده اید، XAML ئه داره در فضای نام پروژه شما تفسیر میشه و اون Application.Current در همین فضای نام اجرا میشه و برای همین یک شیء از کلاس App رو برمی گردونه، با نوع Application سازگار هست و Application محسوب میشه ولی نوع داده اش App ئه.

خیلی ممنون استاد .
من دقیقا متوجه نشدم .
بله . Application.Current را فراخونی کرده که این پروپرتی ، شی ای از کلاس Application را برمیگردونه :

Application.Current Property (System.Windows)

توی سلسله مراتب ارث بری در مایکروسافت (بصورت رسمی) هم بصورت Object>DispatcherObject>Application هست و بعد از کلاس Application هم کلاس دیگه ای بصورت رسمی نیومد . بنابراین بعید میدونم که پروپرتیِ Application.Current ، شی ای از کلاسی را برگردونه که فرزند کلاس Application (مثل کلاس App که داده بودین) باشه .
کلا من دقیقا متوجه ی منظورتون نشدم .

زیر مثال نوشته بود که For the full example, see Data Binding Demo و لینک اش دیگه مثل سابق به مسیر مناسب هدایت نمیشد. در گوگل دنبال specialFeaturesConverter گشتم و پیدا شد.


فوت کوزه گری خاصی نداره، صرفا حاصل تجربه است و کمی هم عادت به تند خوانی. وقتی در یک موردی تجربه تون زیاد بشه کارهای مشابه اش رو به سادگی و به سرعت انجام می دهید.

خیلی ممنون استاد .

----------------------------------------------------------

استاد ، در لینک زیر :

Binding.Path Property (System.Windows.Data)

و در مثالش که :

کد:
<Style x:Key="textBoxInError" TargetType="{x:Type TextBox}">
  <Style.Triggers>
    <Trigger Property="Validation.HasError" Value="true">
      <Setter Property="ToolTip"
        Value="{Binding RelativeSource={x:Static RelativeSource.Self},
                        Path=(Validation.Errors)/ErrorContent}"/>
    </Trigger>
  </Style.Triggers>
</Style>

هست ، اون RelativeSource.Self منظورش شیِ کلاس Setter میشه که داره در اون شیِ کلاسِ Setter ازش استفاده میکنه یا منظورش شیِ کلاس TextBox (که در پروپرتیِ TargetType در Style مشخص کرده بود)؟
هر چند در این مثال ، متوجه نشدم که مسیر Path ، کدوم عضو یا پروپرتی میشه . فکر کنم باید قضیه ی Validation در Binding را بخونم تا متوجه شم .
اگه منظوررش شیِ کلاس Setter نیست ، پس چطور در لینک زیر :

RelativeSources in WPF

در مثال :

کد:
<Rectangle Fill="Red" Height="100"
                   Stroke="Black"
                   Width="{Binding RelativeSource={RelativeSource Self},
                   Path=Height}"/>

منظورش همون شی ای که در درونش داره از RelativeSource Self استفاده میکنه (یعنی شی Rectangle) ، منظورش همین شی هست اما در کد بالاتر نیست؟
 

the_king

مدیرکل انجمن
من دقیقا متوجه نشدم .
بله . Application.Current را فراخونی کرده که این پروپرتی ، شی ای از کلاس Application را برمیگردونه :

Application.Current Property (System.Windows)

توی سلسله مراتب ارث بری در مایکروسافت (بصورت رسمی) هم بصورت Object>DispatcherObject>Application هست و بعد از کلاس Application هم کلاس دیگه ای بصورت رسمی نیومد . بنابراین بعید میدونم که پروپرتیِ Application.Current ، شی ای از کلاسی را برگردونه که فرزند کلاس Application (مثل کلاس App که داده بودین) باشه .
کلا من دقیقا متوجه ی منظورتون نشدم .
"بعید میدونم" یعنی "احتمال خیلی کمی میدم که درست باشه"، اما تو کد برنامه که احتمالات اجرا نمیشه، کد مطلق ئه. یا هست یا نیست. این کد رو امتحان کنید، ببینید نوع اش چیه :
کد:
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(Application.Current.GetType().FullName);
        }
منطقش که خیلی ساده است، در کد ()Control c = new Button شیء از نوع Button ئه، مهم نیست که c از نوع Button نیست، شیء داخل c یک Button ئه. چه در object قرار بگیره و چه Control و چه هر وراثت سازگار دیگری همچنان Button ئه.

اون RelativeSource.Self منظورش شیِ کلاس Setter میشه که داره در اون شیِ کلاسِ Setter ازش استفاده میکنه یا منظورش شیِ کلاس TextBox (که در پروپرتیِ TargetType در Style مشخص کرده بود)؟
منظور TextBox ئه. کاری با Setter نداره. اینطوری به قضیه نگاه کنید، شما یک Style دارید که یک Target ای داره که هر چی می نویسه برای اونه، مثلا یک TextBox.
حالا Setter داره برای ToolTip کدوم شیء مقدار تعیین می کنه؟ ToolTip اون TextBox ئه. الان توصیف داخل Style برای چه شیء ای است؟ برای اون TextBox ئه. Self کیه؟ TextBox ئه.
هر چند در این مثال ، متوجه نشدم که مسیر Path ، کدوم عضو یا پروپرتی میشه . فکر کنم باید قضیه ی Validation در Binding را بخونم تا متوجه شم .
اگه منظوررش شیِ کلاس Setter نیست ، پس چطور در لینک زیر :

RelativeSources in WPF

در مثال :

کد:
<Rectangle Fill="Red" Height="100"
                   Stroke="Black"
                   Width="{Binding RelativeSource={RelativeSource Self},
                   Path=Height}"/>

منظورش همون شی ای که در درونش داره از RelativeSource Self استفاده میکنه (یعنی شی Rectangle) ، منظورش همین شی هست اما در کد بالاتر نیست؟
اینطوریه چون روال اش اینطوریه. Self یک کلمه کلیدی مثل this نیست، Extension ئه، کد داره، روال داره. RelativeSource Self کاری رو انجام میده که برایش کد نویسی شده، باید دنبال چیزی باشه که برایش Bind کردن معنی بده. Setter میگه مقدار فلان رو بکن بهمان. خود Setter منبع داده است؟ نه فلان برای Setter متغیر ئه و نه بهمان. Setter فقط فرمان میده.
چیزی در خود Setter تغییر می کنه که مورد دیگری بهش وابسته بشه؟
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلی ممنون استاد.
استاد ، در کد زیر :

کد:
<Button>
  <Button.ContextMenu>
    <ContextMenu>
      <MenuItem Header="1">First item</MenuItem>
      <MenuItem Header="2">Second item</MenuItem>
    </ContextMenu>
  </Button.ContextMenu>
  Right-click me!</Button>

ما وقتی متوجه میشیم که چند تا تگ به عنوان مقدار (مثل تگ های MenuItem در بالا) به یه property element (مثل ContextMenu در بالا) بدیم که نوعی که اون property element قبول میکنه ، از نوع آرایه یا کلا collection باشه .
در مثال بالا ، پروپرتیِ ContextMenu که از نوع و کلاس ContextMenu هست و نوع ContextMenu هم که کالکشن نیست .
پس چجوری شد که در کد بالا ، به این روش و با اون سینکس کد نوشت؟
ما در این مواقع از کجا متوجه بشیم که میتونیم چندین تک را به عنوان مقدار برای اون property element مون در نظر بگیریم؟ (بجز برای کالکشن ها) .
 

the_king

مدیرکل انجمن
خیلی ممنون استاد.
استاد ، در کد زیر :

کد:
<Button>
  <Button.ContextMenu>
    <ContextMenu>
      <MenuItem Header="1">First item</MenuItem>
      <MenuItem Header="2">Second item</MenuItem>
    </ContextMenu>
  </Button.ContextMenu>
  Right-click me!</Button>

ما وقتی متوجه میشیم که چند تا تگ به عنوان مقدار (مثل تگ های MenuItem در بالا) به یه property element (مثل ContextMenu در بالا) بدیم که نوعی که اون property element قبول میکنه ، از نوع آرایه یا کلا collection باشه .
در مثال بالا ، پروپرتیِ ContextMenu که از نوع و کلاس ContextMenu هست و نوع ContextMenu هم که کالکشن نیست .
پس چجوری شد که در کد بالا ، به این روش و با اون سینکس کد نوشت؟
ما در این مواقع از کجا متوجه بشیم که میتونیم چندین تک را به عنوان مقدار برای اون property element مون در نظر بگیریم؟ (بجز برای کالکشن ها) .
دارید اشتباه تفسیر می کنید، چیزی که داخل تگ ContextMenu میاد توصیف خود ContextMenu ئه، نه توصیف Button.ContextMenu. اون Button ئه فقط یک شیء برای مشخصه ContextMenu اش داره، اینکه شیء ConextMenu ئه چند تا MenuItem داخل خودش داره که ربطی به مجموعه بودن و نبودن Button.ContextMenu نداره.
MenuItem ها به عنوان عضو یک ContextMenu تعریف می شوند، نه اعضاء Button.ContextMenu.
Button.ContextMenu از ما یک ContextMenu میخواد و فقط یک ContextMenu برایش توصیف کرده ایم، دو سه تا که نشده.
ContextMenu هم که یک ItemsControl ئه و با اینکه یکسری Item داخلش داره مشکلی نداریم.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
دارید اشتباه تفسیر می کنید، چیزی که داخل تگ ContextMenu میاد توصیف خود ContextMenu ئه، نه توصیف Button.ContextMenu. اون Button ئه فقط یک شیء برای مشخصه ContextMenu اش داره، اینکه شیء ConextMenu ئه چند تا MenuItem داخل خودش داره که ربطی به مجموعه بودن و نبودن Button.ContextMenu نداره.
MenuItem ها به عنوان عضو یک ContextMenu تعریف می شوند، نه اعضاء Button.ContextMenu.
Button.ContextMenu از ما یک ContextMenu میخواد و فقط یک ContextMenu برایش توصیف کرده ایم، دو سه تا که نشده.
ContextMenu هم که یک ItemsControl ئه و با اینکه یکسری Item داخلش داره مشکلی نداریم.

سلامی مجدد
خیلی ممنون استاد
:green:
یه لحظه قاتی کردم رفتم .
به عبارتی دیگه ، کد پست قبلی رو میشه این طور نوشت :

کد:
                <Button  HorizontalAlignment="Left" Height="44" Margin="10,780,0,0" VerticalAlignment="Top" Width="116">
                    <Button.ContextMenu>
                        <ContextMenu>
                            <ContextMenu.Items>
                                <MenuItem Header="1">First item</MenuItem>
                                <MenuItem Header="2">Second item</MenuItem>
                            </ContextMenu.Items>
                        </ContextMenu>
                    </Button.ContextMenu>
                    Right-click me!
                </Button>

در واقع ، ContextMenu.Items هست که آرایه و کالکشن میگیره .

--------------------------------------------------------------------

استاد ، در مثال زیر :

کد:
                <ComboBox Name="myComboBox1" Height="28" Margin="10,154,0,0"  VerticalAlignment="Top" Width="201" SelectedIndex="0" Background="#FF2300FF" BorderBrush="Red" HorizontalAlignment="Left" RenderTransformOrigin="0.5,0.5">
                    <ComboBox.Items>
                        <System:String>salam</System:String>
                        <System:String>khobi?</System:String>
                    </ComboBox.Items>

                    <ComboBox.ItemContainerStyle>
                        <Style TargetType="ComboBoxItem">
                            <Setter Property="Background" Value="#FF9AD2F1"/>
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                                        <Border Name="Border" Background="{TemplateBinding Background}">
                                            <Border.Child>
                                                <ContentPresenter />
                                            </Border.Child>
                                        </Border>
                                        <ControlTemplate.Triggers>
                                            <Trigger Property="IsHighlighted" Value="True">
                                                <Setter Property="Background" TargetName="Border" Value="#FFEC9898" />
                                            </Trigger>
                                        </ControlTemplate.Triggers>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </ComboBox.ItemContainerStyle>
                </ComboBox>

اونجایی که نوشته ComboBox.ItemContainerStyle و ما به این پروپرتی ، مقدار Style میدیم و به پروپرتی TargetType ئه مربوط به Style ، نوعِ ComboBoxItem میدیم .
از کجا باید متوجه بشیم که چه نوعی را باید در TargetType ئه مربوط به Style مشخص کنیم؟
من الان در مثال بالا نمیدونستم چه نوعی را باید بدم . راهکارم این بود که از قصد ، یه نوعی که احتمال میدادم اشتباه باشه (مثلا نوع Button) را در کد بالا میدادم و منتظر میموندم تا مفسر xaml در wpf ارور بده . توی اون ارور ، مشخص میکرد که نوعش باید ComboBoxItem باشه و این مقدارش را از اونجا متوجه میشدم و میذاشتم . اما بصورت اصولی ، الان باید در مثال بالا ، نوع TargetType ئه مربوط به Style را از کجا متوجه بشیم؟
 

the_king

مدیرکل انجمن
اونجایی که نوشته ComboBox.ItemContainerStyle و ما به این پروپرتی ، مقدار Style میدیم و به پروپرتی TargetType ئه مربوط به Style ، نوعِ ComboBoxItem میدیم .
از کجا باید متوجه بشیم که چه نوعی را باید در TargetType ئه مربوط به Style مشخص کنیم؟
من الان در مثال بالا نمیدونستم چه نوعی را باید بدم . راهکارم این بود که از قصد ، یه نوعی که احتمال میدادم اشتباه باشه (مثلا نوع Button) را در کد بالا میدادم و منتظر میموندم تا مفسر xaml در wpf ارور بده . توی اون ارور ، مشخص میکرد که نوعش باید ComboBoxItem باشه و این مقدارش را از اونجا متوجه میشدم و میذاشتم . اما بصورت اصولی ، الان باید در مثال بالا ، نوع TargetType ئه مربوط به Style را از کجا متوجه بشیم؟
ItemsControl.ItemContainerStyle از نوع Style ئه به همین جهت در وراثت نوع خاص دیگری نمیشه و Style میمونه.
راه های زیادی هست، مثلا اینکه در ComboBox Styles and Templates بجز ComboBox چه Part دیگری هست. چون ItemsControl ئه حتی اگه کنترل ئه پنج تا Part هم داشته باشه طبعا نوع یک Part ای که در Style اش مشخص میشه باید برای ItemContainerStyle باشه.
یک راه دیگه اینه که موقع طراحی روی کنترل راست کلیک کنید و گزینه ...Edit Additional Templates > Edit Generated Item Container (ItemContainerStyle) > Create Empty رو انتخاب کنید و ببینید ControlTemplate رو از چه نوعی می سازه.
یک راه حل دیگه اینه در کدتون یک ComboBox بنویسید و F12 رو فشار دهید و صفات بالای کلاس رو باز کنید و ببینید در صفات کلاس اش StyleTypedProperty رو با چه نوع ای برای ItemContainerStyle نوشته.
مثلا :
کد:
    [Localizability(LocalizationCategory.ComboBox)]
    [StyleTypedProperty(Property = "ItemContainerStyle", StyleTargetType = typeof(ComboBoxItem))]
    [TemplatePart(Name = "PART_EditableTextBox", Type = typeof(TextBox))]
    [TemplatePart(Name = "PART_Popup", Type = typeof(Popup))]
    public class ComboBox : Selector
    {
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
ItemsControl.ItemContainerStyle از نوع Style ئه به همین جهت در وراثت نوع خاص دیگری نمیشه و Style میمونه.
راه های زیادی هست، مثلا اینکه در ComboBox Styles and Templates بجز ComboBox چه Part دیگری هست. چون ItemsControl ئه حتی اگه کنترل ئه پنج تا Part هم داشته باشه طبعا نوع یک Part ای که در Style اش مشخص میشه باید برای ItemContainerStyle باشه.
یک راه دیگه اینه که موقع طراحی روی کنترل راست کلیک کنید و گزینه ...Edit Additional Templates > Edit Generated Item Container (ItemContainerStyle) > Create Empty رو انتخاب کنید و ببینید ControlTemplate رو از چه نوعی می سازه.
یک راه حل دیگه اینه در کدتون یک ComboBox بنویسید و F12 رو فشار دهید و صفات بالای کلاس رو باز کنید و ببینید در صفات کلاس اش StyleTypedProperty رو با چه نوع ای برای ItemContainerStyle نوشته.
مثلا :
کد:
    [Localizability(LocalizationCategory.ComboBox)]
    [StyleTypedProperty(Property = "ItemContainerStyle", StyleTargetType = typeof(ComboBoxItem))]
    [TemplatePart(Name = "PART_EditableTextBox", Type = typeof(TextBox))]
    [TemplatePart(Name = "PART_Popup", Type = typeof(Popup))]
    public class ComboBox : Selector
    {

سلامی مجدد
خیلی ممنون استاد .
این روش آخری (اتریباتسِ StyleTypedProperty) گفتین ، به نظرم از روش های دیگه راحت تر و دقیق تر هست . پس به این شیوه عمل میکنم .

--------------------------------------------

استاد ، content property ، همین چیزی هه که وقتی بصورت صریح ، پروپرتی ای از یک کلاسی را مشخص نمیکنیم اما وقتی content (از لحاظ xml) ای را برای اون شی از کلاسی که اون پروپرتی را داره (بدون اینکه صریحا نام اون پروپرتی را ببریم) ، در نظر میگیریم ، مقدار اون content را برای اون پروپرتی ست میکنه . درسته؟
و با استفاده از اتریباتسِ ContentPropertyAttribute میشه content property را برای اون پروپرتی ، ست کرد . درسته؟
content property هم در کلاس با اون اتریباتس ، اگه در کلاس پدر ، بکار بره ، کلاس فرزندان را هم شامل میشه . و همچنین مثل حالت virtual - override ، اگه در چند مرحله در سلسله مراتب ارث بری بکار بره ، اون آخرین کلاسی که براش این اتریباتس (برای پروپرتیِ خاصی از اون کلاس) در نظر گرفته شد ، به عنوان content property تعیین میشه . درسته؟

مثلا در کد پست 172 که همین کد زیر هست :

کد:
<Button>
  <Button.ContextMenu>
    <ContextMenu>
      <MenuItem Header="1">First item</MenuItem>
      <MenuItem Header="2">Second item</MenuItem>
    </ContextMenu>
  </Button.ContextMenu>
  Right-click me!</Button>

چون برای اولین جد کلاس ContextMenu که اتریباتسِ ContentProperty تعیین شد (که همون کلاس ItemsControl هست با مقدار ContentProperty("Items") هست) (که این اتریباتس هم پروپرتیِ Items را به عنوان content property تعیین کرد) ، پس هر جا که از کلاس ItemsControl یا فرزندانش (که در اینجا کلاس ContextMenu هست) ، در xaml ، شی (تگ) ساخته بشه و اگه پروپرتی ای را مشخص نکنن اما به این تگ ، یک content (محتوا از لحاظ کدهای xml) بدن ، اون محتوا ، به عنوان مقدارِ این پروپرتیِ Items (همونطور که به ترتیبی که در بالا گفته شد) ، در نظر گرفته میشه .
پس به این ترتیب ، مقادیر (محتوای) :

کد:
      <MenuItem Header="1">First item</MenuItem>
      <MenuItem Header="2">Second item</MenuItem>

برای پروپرتیِ ContextMenu.Items در نظر گرفته میشه .
همچنین وقتی به Button در بالا ، محتوا (از لحاظ xml) ئه "Right-click me!" داده شد ، چون برای اولین جد Button ای که اون اتریباتسِ ContentProperty تعیین شد ، اون کلاس ، کلاسِ ContentControl (با مقدار ContentProperty("Content") ) هست ، پس اون محتوای "Right-click me!" ، برای پروپرتیِ Button.Content در نظر گرفته میشه .
درسته؟
 

the_king

مدیرکل انجمن
استاد ، content property ، همین چیزی هه که وقتی بصورت صریح ، پروپرتی ای از یک کلاسی را مشخص نمیکنیم اما وقتی content (از لحاظ xml) ای را برای اون شی از کلاسی که اون پروپرتی را داره (بدون اینکه صریحا نام اون پروپرتی را ببریم) ، در نظر میگیریم ، مقدار اون content را برای اون پروپرتی ست میکنه . درسته؟
و با استفاده از اتریباتسِ ContentPropertyAttribute میشه content property را برای اون پروپرتی ، ست کرد . درسته؟
از ContentPropertyAttribute استفاده می کنیم ولی تا اونجایی که به کلاس مربوط ئه خیلی صریح ئه، از نظر کد نویسی صراحت داره، اگه صریح نباشه Content توصیف کردن برای XAML کارکرد نداره.
اینکه برای یک تگ Content توصیف می کنید نتیجه اش این نمیشه که خود XAML برای کلاس اش دنبال مشخصه Content بگرده.
و کلا کاری با اسم مشخصه نداره، بر اساس اضافه کردن صفت ContentProperty یا پیاده سازی اینترفیس IAddChild عمل می کنه، البته IAddChild منسوخ شده (obsolete ئه).
در کلاس وجود ContentProperty یا IAddChild کفایت می کنه تا XAML بتونه برای Content کارکرد مناسبش رو پیدا کنه.

content property هم در کلاس با اون اتریباتس ، اگه در کلاس پدر ، بکار بره ، کلاس فرزندان را هم شامل میشه . و همچنین مثل حالت virtual - override ، اگه در چند مرحله در سلسله مراتب ارث بری بکار بره ، اون آخرین کلاسی که براش این اتریباتس (برای پروپرتیِ خاصی از اون کلاس) در نظر گرفته شد ، به عنوان content property تعیین میشه . درسته؟
بله. یک قاعده کلی در #C ئه، صفات در وارث به ارث می رسند، مستقل از اینکه پلتفرم چی باشه.

مثلا در کد پست 172 که همین کد زیر هست :

کد:
<Button>
  <Button.ContextMenu>
    <ContextMenu>
      <MenuItem Header="1">First item</MenuItem>
      <MenuItem Header="2">Second item</MenuItem>
    </ContextMenu>
  </Button.ContextMenu>
  Right-click me!</Button>

چون برای اولین جد کلاس ContextMenu که اتریباتسِ ContentProperty تعیین شد (که همون کلاس ItemsControl هست با مقدار ContentProperty("Items") هست) (که این اتریباتس هم پروپرتیِ Items را به عنوان content property تعیین کرد) ، پس هر جا که از کلاس ItemsControl یا فرزندانش (که در اینجا کلاس ContextMenu هست) ، در xaml ، شی (تگ) ساخته بشه و اگه پروپرتی ای را مشخص نکنن اما به این تگ ، یک content (محتوا از لحاظ کدهای xml) بدن ، اون محتوا ، به عنوان مقدارِ این پروپرتیِ Items (همونطور که به ترتیبی که در بالا گفته شد) ، در نظر گرفته میشه .
بله.

پس به این ترتیب ، مقادیر (محتوای) :

کد:
      <MenuItem Header="1">First item</MenuItem>
      <MenuItem Header="2">Second item</MenuItem>

برای پروپرتیِ ContextMenu.Items در نظر گرفته میشه .
همچنین وقتی به Button در بالا ، محتوا (از لحاظ xml) ئه "Right-click me!" داده شد ، چون برای اولین جد Button ای که اون اتریباتسِ ContentProperty تعیین شد ، اون کلاس ، کلاسِ ContentControl (با مقدار ContentProperty("Content") ) هست ، پس اون محتوای "Right-click me!" ، برای پروپرتیِ Button.Content در نظر گرفته میشه .
درسته؟
بله. دقیقا.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلی ممنون استاد .
استاد ، دارم مقاله ی زیر را میخونم :

XAML Syntax In Detail - WPF

به بخش Attached Events رسیدم .
این قدر خلاصه توضیح داد که چیزی متوجه نشدم .
بعد دیدم درباره ی Attached Events ، مقاله ی زیر هست :

Attached Events Overview - WPF

این مقاله هم میگه پیش نیازش ، مقاله ی XAML Overview (که این مقاله را کامل خوندم) و Routed Events Overview (که این مقاله را فقط یک نگاه بسیار اجمالی کردم در همون حد که قبلا ازتون پرسیده بودم و خبر دارین) هست .
زحمتا ، Attached Events را بصورت خیلی خلاصه توضیح میدین که فقط کلیاتش چجوری هه؟ (در حد 2 تا 3 خط توضیح)
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
استاد ، دارم مقاله ی زیر را میخونم :

XAML Syntax In Detail - WPF

به بخش Attached Events رسیدم .
این قدر خلاصه توضیح داد که چیزی متوجه نشدم .
بعد دیدم درباره ی Attached Events ، مقاله ی زیر هست :

Attached Events Overview - WPF

این مقاله هم میگه پیش نیازش ، مقاله ی XAML Overview (که این مقاله را کامل خوندم) و Routed Events Overview (که این مقاله را فقط یک نگاه بسیار اجمالی کردم در همون حد که قبلا ازتون پرسیده بودم و خبر دارین) هست .
زحمتا ، Attached Events را بصورت خیلی خلاصه توضیح میدین که فقط کلیاتش چجوری هه؟ (در حد 2 تا 3 خط توضیح)
رخداد های عادی مربوط به اشیاء ای بودند که در WPF توصیف کرده بودید، مثلا یک Button داشتید که برای رخداد Click اش کاری انجام می دادید یا بصورت Routed Events برای یکسری Button ها کاری انجام میشد اما در هر صورت Button ای باید وجود میداشت که Click اش اجرا بشه، رخداد بر اساس وجود شیء بود، Instance داشت. اگر شیء دکمه ای وجود نداشت Click شدنش بی معنی بود.
اما Attached Events بر اساس شیء نیست، static ئه. مثلا Mouse.MouseDown رو بکار می برید اما در XAML شیء Mouse ای رو توصیف نمی کنید، Mouse ئه یک کلاس static ئه.
از Attached Events در جایی استفاده میشه که رخداد ئه بر اساس وجود اشیاء نیست و حالت static داره.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلامی مجدد
خیلی ممنون استاد.
استاد ، طبق لینک زیر (بخش آخرش) :

XAML Syntax In Detail - WPF

اگه توی کلاسی ، از پروپرتیِ یک کلاسِ دیگه استفاده کنیم ، پردازنده ی xaml در wpf ، اون پروپرتی را به عنوان attached property میشناسه . درسته؟
مثلا در تگ Button ای ، به عنوان attributes اش ، از Label.Background استفاده کنیم ، در این صورت ، پردازنده ی xaml در wpf ، این روپرتی را سعی میکنه به عنوان attached property پردازش کنه اما چون این پروپرتیِ Label.Background در راهنمای سایت اش (و کلا) به عنوان attached property مشخص نشد ، پس ارور میده . درسته؟


___________________

بعد اینکه استاد ، به نظرتون چطوره هر بخش را که تمام میکنم ، آموزش همون قسمت را هم بدم؟
چون wpf ، اگه بخوایم به ریزترین جزئیاتش بپردازم ، اولا که خیلی طول میکشه و دوما که چون پروسه ی آموزش طول میکشه ، اگه این جزئیات را الان بخونم و بعد بخوام آموزشش را درست کنم ، حداقل ۴ ماه طول میکشه و توی این ۴ ماه ، دوباره این جزئیات را فراموش میکنم و مجبورم دوباره بخونم و همچنین اینکه هیچ آموزش wpf را ندیدم که به جزئیاتِ چندانی بپردازه (البته منظورم این نیست که من نپردازم یا حتما بپردازم) ، به نظرتون چطوره هر موقع که مقاله و مبحثی را میخونم ، همون موقع آموزشش را هم بدم؟
 
آخرین ویرایش:

جدیدترین ارسال ها

بالا