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

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
نه. اون VisualStateManager.VisualStateGroups یک مشخصه الحاقی ئه، جزو مشخصه های Grid نیست. مثل همون Storyboard.TargetName که در پست #51 گفتم. در همون پست به این مساله اشاره کردم که هر چیزی که در بخش content نوشته میشه الزاما ربطی به مشخصه های اون کلاس نداره. بعضی ویژگی ها خاص WPF ئه، در #C دنبال هر چیزی که در WPF دیدید نگردید.

خیلی ممنون استاد . :rose:
عیدتون مبارک :rose:

مشخصه های الحاقی دیگه چی هستند؟
منظورتون اینه که چیزهایی که مشخصه ی الحاقی هستند را نمیشه با کد سی شارپ نوشت و فقط با کدهای xml در wpf میشه نوشت؟ (یعنی قابلیت تبدیل به کد سی شارپ توشون نیست؟)
خود کدهای xml مگه در wpf بصورت نهان به کدهای سی شارپ تبدیل نمیشه؟ (تا موقع اجرای اپلیکیشن ، به کدهای clr تبدیل بشه؟) . اگه نه ، یعنی مستقیما به کدهای clr تبدیل میشه؟
الان من از کجا متوجه بشم که کجاها میتونم مشخصه ی الحاقی در xml در wpf بکار ببرم؟


پدر و فرزندی در کار نیست، مثل IntPtr.Zero که Zero فیلد static ئه، Zero که فرزند IntPtr نیست، IntPtr رو می نویسیم تا struct اش مشخص بشه.
در واقع VisualStateGroupsProperty ئه که یک DependencyProperty ئه static بوده، اون VisualStateManager برای مشخص کردن کلاس ای است که VisualStateGroupsProperty بهش تعلق داره.

منظورم تگ های پدر و فرزند در xml هست .
منظورم رابطه ی پدر و فرزند در سی شارپ نیست .
کلا این کد یه کم برام ناآشناست . از قواعدش گیج شدم و نمیدونم چی شد و از کجا باید متوجه شد که کدِ VisualStateManager.VisualStateGroups را به عنوان محتوا (content در xml) درون تگ Grid داد؟
راستی اعضای استاتیک (اگه در کلاسی باشن) ، در xml ، مثل اعضای شی گرا به عنوان attributes مقداردهی میشن؟
 

the_king

مدیرکل انجمن
خیلی ممنون استاد . :rose:
عیدتون مبارک :rose:
ممنونم. سال نو برای شما هم مبارک باشه.
مشخصه های الحاقی دیگه چی هستند؟
Attached Property ها هستند. مشخصه هایی که برای اجزاء ای قابل استفاده هستند، در حالی که جزو مشخصه های اونها نیستند.
فرضا می خواهید بگید این Border که دارم تعریف می کنم باید در ستون اندیس 0 نمایش داده بشه، Grid.Column نه فرزند Grid ئه و نه Column جزو مشخصه های Border ئه. با Grid.Column که مشخصه الحاقی است مشخص می کنیم که این Border وقتی بخواد در Grid نمایش داده بشه محل قرار گیری اش اندیس 0 ئه.

منظورتون اینه که چیزهایی که مشخصه ی الحاقی هستند را نمیشه با کد سی شارپ نوشت و فقط با کدهای xml در wpf میشه نوشت؟ (یعنی قابلیت تبدیل به کد سی شارپ توشون نیست؟)
مشخصه الحاقی در #C معادلی نداره، برای توصیف در XAML ئه. شما در #C می توانید کاری که مشخصه الحاقی انجام میداد رو با متد های متعارف که در #C هست انجام بدید، اما دیگه مشخصه الحاقی نیست.
مثلا Button1.Column = 1 یا Button1.Grid.Column = 1 یا چیز هایی مثل این در #C معنی نمیده، با Grid.SetColumn(Button1, 1) یا Button1.SetValue(Grid.ColumnProperty, 1) همچین کاری رو می کنید که SetColumn یک متد static عادی ئه و SetValue یک متد public کلاس ئه، همون نتیجه رو می گیرید ولی معادل مشخصه الحاقی نیست.

خود کدهای xml مگه در wpf بصورت نهان به کدهای سی شارپ تبدیل نمیشه؟ (تا موقع اجرای اپلیکیشن ، به کدهای clr تبدیل بشه؟) . اگه نه ، یعنی مستقیما به کدهای clr تبدیل میشه؟
نه. قرار نیست یک فرمت توصیفی به زبان برنامه نویسی یا زبان ماشین تبدیل بشه. قبلا در مورد XML و اینکه یک زبان برنامه نویسی نیست صحبت کردیم، برنگردید سر خونه اول.
کد XML یک چیزی رو توصیف می کنه، تفسیر میشه تا اون اجزاء رو بسازه، دلیلی نداره تبدیل به کد #C یا CLR بشه چون کد اجرایی نیست، به سادگی یک resource میشه.
موقعی که فایل اجرایی ساخته میشه XAML ها بصورت باینری ترجمه میشن که پسوند BAML داره، که سرعت فراخوانی اش بالاتر از تفسیر متن ساده است. می توانید در مورد Binary Application Markup Language مطالعه کنید. همانطور که شما در برنامه هاتون فرم ها resource خودشون رو دارند و ضمیمه میشه به فایل اجرایی، این baml ها هم ضمیمه فایل اجرایی برنامه تون می شوند.

الان من از کجا متوجه بشم که کجاها میتونم مشخصه ی الحاقی در xml در wpf بکار ببرم؟
برعکس به قضیه نگاه کنید، شما فرضا کار با Grid رو یاد میگیرید و می بینید برای مشخص کردن Column در اجزاء باید از مشخصه فلان استفاده کنید که در توضیحاتش نوشته مشخصه الحاقی ئه و اگر نمیدونستید مشخصه الحاقی ئه باز هم فرقی نمی کرد. بر عکسش معنی نمیده، یعنی اینطوری نیست که بگم من حالا در این XAML ام کجاها می توانم از مشخصه الحاقی استفاده کنم. اگر بدون استفاده از مشخصه الحاقی Column مشخص شدنی باشه که دیگه مشخصه الحاقی بدرد نمی خوره.

منظورم تگ های پدر و فرزند در xml هست .
منظورم رابطه ی پدر و فرزند در سی شارپ نیست .
در جواب فرقی نمی کنه.

کلا این کد یه کم برام ناآشناست . از قواعدش گیج شدم و نمیدونم چی شد و از کجا باید متوجه شد که کدِ VisualStateManager.VisualStateGroups را به عنوان محتوا (content در xml) درون تگ Grid داد؟
با خواندن مستندات WPF. وقتی ندونید WPF چطور خصوصیات بصری رو توصیف می کنه طبعا کد توصیفی اش رو هم نمی توانید درک کنید.

راستی اعضای استاتیک (اگه در کلاسی باشن) ، در xml ، مثل اعضای شی گرا به عنوان attributes مقداردهی میشن؟
نه. تا جایی که اطلاع دارم هنوز همچین قابلیتی در نظر گرفته نشده. می توانید مقدار بگیرید اما نمی توانید مستقیما مقدار بدهید.
ممکنه یک کلاسی بیاد از طریق یک مشخصه non-static اش فیلد static ای رو تغییر بده اما در کد #C اینکار رو کرده، نه در XAML
مشخصه XML برای یک المنت ای است، شیء داره، صاحب داره. مقدار مشخصه static با {... x:Static}"= دریافت میشه اما سمت چپ که attributes ئه برای مشخص کردن یک مقدار برای شیء فلان ئه، یعنی Instance داره، برای یک مشخصه static نیست. حتی اون مشخصه الحاقی هم که به خود المنت تعلق نداشت مالک داره که بهش متصل شده، حالا ممکنه Instance اش بیاد در کد #C برای فیلد static ای استفاده اش کنه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
ممنونم. سال نو برای شما هم مبارک باشه.

این کلیپ چند ثانیه ای را سال ها قبل که یه کم با افترافکت کار میکردم درست کردم (هر چند مبتدی بودم و جالب نیست) ، تقدیم شما :

gif.gif


Attached Property ها هستند. مشخصه هایی که برای اجزاء ای قابل استفاده هستند، در حالی که جزو مشخصه های اونها نیستند.
فرضا می خواهید بگید این Border که دارم تعریف می کنم باید در ستون اندیس 0 نمایش داده بشه، Grid.Column نه فرزند Grid ئه و نه Column جزو مشخصه های Border ئه. با Grid.Column که مشخصه الحاقی است مشخص می کنیم که این Border وقتی بخواد در Grid نمایش داده بشه محل قرار گیری اش اندیس 0 ئه.


مشخصه الحاقی در #C معادلی نداره، برای توصیف در XAML ئه. شما در #C می توانید کاری که مشخصه الحاقی انجام میداد رو با متد های متعارف که در #C هست انجام بدید، اما دیگه مشخصه الحاقی نیست.
مثلا Button1.Column = 1 یا Button1.Grid.Column = 1 یا چیز هایی مثل این در #C معنی نمیده، با Grid.SetColumn(Button1, 1) یا Button1.SetValue(Grid.ColumnProperty, 1) همچین کاری رو می کنید که SetColumn یک متد static عادی ئه و SetValue یک متد public کلاس ئه، همون نتیجه رو می گیرید ولی معادل مشخصه الحاقی نیست.


نه. قرار نیست یک فرمت توصیفی به زبان برنامه نویسی یا زبان ماشین تبدیل بشه. قبلا در مورد XML و اینکه یک زبان برنامه نویسی نیست صحبت کردیم، برنگردید سر خونه اول.
کد XML یک چیزی رو توصیف می کنه، تفسیر میشه تا اون اجزاء رو بسازه، دلیلی نداره تبدیل به کد #C یا CLR بشه چون کد اجرایی نیست، به سادگی یک resource میشه.
موقعی که فایل اجرایی ساخته میشه XAML ها بصورت باینری ترجمه میشن که پسوند BAML داره، که سرعت فراخوانی اش بالاتر از تفسیر متن ساده است. می توانید در مورد Binary Application Markup Language مطالعه کنید. همانطور که شما در برنامه هاتون فرم ها resource خودشون رو دارند و ضمیمه میشه به فایل اجرایی، این baml ها هم ضمیمه فایل اجرایی برنامه تون می شوند.


برعکس به قضیه نگاه کنید، شما فرضا کار با Grid رو یاد میگیرید و می بینید برای مشخص کردن Column در اجزاء باید از مشخصه فلان استفاده کنید که در توضیحاتش نوشته مشخصه الحاقی ئه و اگر نمیدونستید مشخصه الحاقی ئه باز هم فرقی نمی کرد. بر عکسش معنی نمیده، یعنی اینطوری نیست که بگم من حالا در این XAML ام کجاها می توانم از مشخصه الحاقی استفاده کنم. اگر بدون استفاده از مشخصه الحاقی Column مشخص شدنی باشه که دیگه مشخصه الحاقی بدرد نمی خوره.


در جواب فرقی نمی کنه.


با خواندن مستندات WPF. وقتی ندونید WPF چطور خصوصیات بصری رو توصیف می کنه طبعا کد توصیفی اش رو هم نمی توانید درک کنید.


نه. تا جایی که اطلاع دارم هنوز همچین قابلیتی در نظر گرفته نشده. می توانید مقدار بگیرید اما نمی توانید مستقیما مقدار بدهید.
ممکنه یک کلاسی بیاد از طریق یک مشخصه non-static اش فیلد static ای رو تغییر بده اما در کد #C اینکار رو کرده، نه در XAML
مشخصه XML برای یک المنت ای است، شیء داره، صاحب داره. مقدار مشخصه static با {... x:Static}"= دریافت میشه اما سمت چپ که attributes ئه برای مشخص کردن یک مقدار برای شیء فلان ئه، یعنی Instance داره، برای یک مشخصه static نیست. حتی اون مشخصه الحاقی هم که به خود المنت تعلق نداشت مالک داره که بهش متصل شده، حالا ممکنه Instance اش بیاد در کد #C برای فیلد static ای استفاده اش کنه.

آها خیلی ممنون استاد از توضیح کامل تون .
پس attached property ها :
1) پروپرتی هایی هستند که وقتی در xml ، تگِ پدری ساختیم ، اولا جزء اعضا و کلاس پدر هستند و دوما بتونیم در تگ های فرزندانِ اون پدر (پدر و فرزندی از لحاظ xml) ، در هر کدوم از تگ های اون فرزندان ، مقدار متفاوت و منحصر به فردی به اون پروپرتیِ الحاقی که متعلق به پدر بود ، بدیم . مثل پروپرتیِ Grid.Column که در کد پست 78 که دادین ، هر کدوم از Border ها (که دو تا Border ، فرزند Grid بودن) ، مقدار منحصر به فرد (کلا مقدار جدیدی) به پروپرتیِ الحاقیِ Grid.Column که متعلق به تگ پدر (یعنی کلاس Grid) هست ، میدن .

2) چون این پروپرتی ها متعلق به کلاس و کلا تگ پدر (از لحاظ xml) هستند ، و در تگ فرزندان مقداردهی میشن ، پس وقتی در تگ فرزندان ، چه بصورت attributes و چه بصورت element (از لحاظ xml منظورمه) میخوایم مقداردهی شون کنیم ، چون عملیات ، عملیاتِ مقداردهی کردن هست ، بنابراین داخلِ پروپرتی دیگه نمیشه ریخت .
واسه ی همینه که چه در کد شما (پست 78 که این پروپرتی الحاقی را بصورت attributes مقداردهی کردین) و چه در اون کدی که از اون صفحه در پست 79 دادم (که بصورت المنت (المنت VisualStateManager.VisualStateGroups) مقداردهی کرد) ، توی هیچ کدوم ، اون مقداری که براش در نظر گرفته شد ، داخلِ عضو و پروپرتیِ دیگه ای از اعضای پدر (از لحاظ xml) ، ریخته نمیشه .

درسته؟
------------------------
خوب با این حال ، باز من یه چیز را متوجه نشدم.
الان در کد شما که کد زیر هست :

کد:
        <ControlTemplate x:Key="MyButton" TargetType="{x:Type Button}">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        Grid.Column="0">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
                <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                        Grid.Column="1">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
            </Grid>
        </ControlTemplate>

وقتی عضوِ Grid.Column را در تگ فرزند میخواین مقداردهی کنین ، واضح هست که قبل اش شیِ Grid ای باید به عنوان پدر تعریف بشه تا بتونین به عضوش (یعنی Grid.Column) ، در تگِ فرزندش (یعنی Border) ، دسترسی داشته باشین و مقداردهی اش کنین . که این کار را انجام دادین و قبل از مقداردهیِ Grid.Column در تگِ Border ، تگ Grid را به عنوان پدر ایجاد کردین .
استانداردش هم همینه دیگه . در تعریف پروپرتی الحاقی هم اینه که اصلا باید تگ پدری وجود داشته باشه تا در تگ های فرزندانش بشه پروپرتی های الحاقی پدر را مقداردهی کرد .

حالا چرا در کد زیر (که در پست 79 داده بودم) :

کد:
<ControlTemplate x:Key="roundbutton" TargetType="Button">
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup Name="CommonStates">
                <VisualState Name="Normal">
                </VisualState>
                <VisualState Name="MouseOver">
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</ControlTemplate>

بدون اینکه تگِ پدر را بسازه ، یعنی بدون اینکه بیاد تگِ VisualStateManager را بسازه ، مستقیم رفت تگ VisualStateManager.VisualStateGroups را ساخت و مقداردهی کرد؟
مگه نباید یه همچین کدی شبیه زیر بجای کد بالا مینوشت (که اول تگ پدر را مشخص میکرد) ؟

کد:
<ControlTemplate x:Key="roundbutton" TargetType="Button">
    <Grid>
   
        <VisualStateManager>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup Name="CommonStates">
                <VisualState Name="Normal">
                </VisualState>
                <VisualState Name="MouseOver">
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        </VisualStateManager>
       
    </Grid>
</ControlTemplate>

کلا کد شما و روش بکار بردن و مقداردهی پروپرتی الحاقی تون را متوجه شدم اما این کدی که دادم را متوجه نشدم . توضیح میدین که چرا در اینجا تگ پدر را نساخت؟

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

بعد اینکه در کد زیر :

کد:
    <Grid x:Name="myGrid1">
        <Grid.Resources>
            <SolidColorBrush x:Key="MyBrush" Color="Gold"/>

            <Style TargetType="{x:Type Button}" x:Key="PageBackground">
                <Setter Property="Background" Value="Blue"/>
            </Style>

            <ControlTemplate TargetType="{x:Type Button}" x:Key="RoundButton">
                <Grid>
                    <Ellipse Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" MouseEnter="Ellipse_MouseEnter" MouseLeave="Ellipse_MouseLeave"/>
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>

                </Grid>
            </ControlTemplate>

        </Grid.Resources>
    </Grid>

قبلا گفته بودین که برای Key در کد بالا ، بخاطر این پیشوند تعیین میکنن چون این Key ، جزء اعضا و پروپرتیِ خودِ اون المنت (مثلا المنت SolidColorBrush) نیست .
درسته؟
اگه آره ، پس 2 تا سئوال پیش میاد که اولا پس برای پروپرتی Name در Grid که این پروپرتیِ Name جزء اعضای خودِ Grid هست ، پس چرا پیشوند تعیین میشه؟
و دوما در قضیه ی پروپرتی های الحاقی که درون تگ فرزندان مقداردهی میشن و طبعا جزء اعضای کلاس فرزندان نیستند (بلکه جزء اعضای کلاس پدرش هستند) ، چرا پیشوند به پروپرتی های الحاقی ، تعلق نمیگیره؟
خیلی ممنون استاد :rose:
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
ممنونم. سال نو برای شما هم مبارک باشه.

این کلیپ چند ثانیه ای را سال ها قبل که یه کم با افترافکت کار میکردم درست کردم (هر چند مبتدی بودم و جالب نیست) ، تقدیم شما :

gif.gif


Attached Property ها هستند. مشخصه هایی که برای اجزاء ای قابل استفاده هستند، در حالی که جزو مشخصه های اونها نیستند.
فرضا می خواهید بگید این Border که دارم تعریف می کنم باید در ستون اندیس 0 نمایش داده بشه، Grid.Column نه فرزند Grid ئه و نه Column جزو مشخصه های Border ئه. با Grid.Column که مشخصه الحاقی است مشخص می کنیم که این Border وقتی بخواد در Grid نمایش داده بشه محل قرار گیری اش اندیس 0 ئه.


مشخصه الحاقی در #C معادلی نداره، برای توصیف در XAML ئه. شما در #C می توانید کاری که مشخصه الحاقی انجام میداد رو با متد های متعارف که در #C هست انجام بدید، اما دیگه مشخصه الحاقی نیست.
مثلا Button1.Column = 1 یا Button1.Grid.Column = 1 یا چیز هایی مثل این در #C معنی نمیده، با Grid.SetColumn(Button1, 1) یا Button1.SetValue(Grid.ColumnProperty, 1) همچین کاری رو می کنید که SetColumn یک متد static عادی ئه و SetValue یک متد public کلاس ئه، همون نتیجه رو می گیرید ولی معادل مشخصه الحاقی نیست.


نه. قرار نیست یک فرمت توصیفی به زبان برنامه نویسی یا زبان ماشین تبدیل بشه. قبلا در مورد XML و اینکه یک زبان برنامه نویسی نیست صحبت کردیم، برنگردید سر خونه اول.
کد XML یک چیزی رو توصیف می کنه، تفسیر میشه تا اون اجزاء رو بسازه، دلیلی نداره تبدیل به کد #C یا CLR بشه چون کد اجرایی نیست، به سادگی یک resource میشه.
موقعی که فایل اجرایی ساخته میشه XAML ها بصورت باینری ترجمه میشن که پسوند BAML داره، که سرعت فراخوانی اش بالاتر از تفسیر متن ساده است. می توانید در مورد Binary Application Markup Language مطالعه کنید. همانطور که شما در برنامه هاتون فرم ها resource خودشون رو دارند و ضمیمه میشه به فایل اجرایی، این baml ها هم ضمیمه فایل اجرایی برنامه تون می شوند.


برعکس به قضیه نگاه کنید، شما فرضا کار با Grid رو یاد میگیرید و می بینید برای مشخص کردن Column در اجزاء باید از مشخصه فلان استفاده کنید که در توضیحاتش نوشته مشخصه الحاقی ئه و اگر نمیدونستید مشخصه الحاقی ئه باز هم فرقی نمی کرد. بر عکسش معنی نمیده، یعنی اینطوری نیست که بگم من حالا در این XAML ام کجاها می توانم از مشخصه الحاقی استفاده کنم. اگر بدون استفاده از مشخصه الحاقی Column مشخص شدنی باشه که دیگه مشخصه الحاقی بدرد نمی خوره.


در جواب فرقی نمی کنه.


با خواندن مستندات WPF. وقتی ندونید WPF چطور خصوصیات بصری رو توصیف می کنه طبعا کد توصیفی اش رو هم نمی توانید درک کنید.


نه. تا جایی که اطلاع دارم هنوز همچین قابلیتی در نظر گرفته نشده. می توانید مقدار بگیرید اما نمی توانید مستقیما مقدار بدهید.
ممکنه یک کلاسی بیاد از طریق یک مشخصه non-static اش فیلد static ای رو تغییر بده اما در کد #C اینکار رو کرده، نه در XAML
مشخصه XML برای یک المنت ای است، شیء داره، صاحب داره. مقدار مشخصه static با {... x:Static}"= دریافت میشه اما سمت چپ که attributes ئه برای مشخص کردن یک مقدار برای شیء فلان ئه، یعنی Instance داره، برای یک مشخصه static نیست. حتی اون مشخصه الحاقی هم که به خود المنت تعلق نداشت مالک داره که بهش متصل شده، حالا ممکنه Instance اش بیاد در کد #C برای فیلد static ای استفاده اش کنه.

آها خیلی ممنون استاد از توضیح کامل تون .
پس attached property ها :
1) پروپرتی هایی هستند که وقتی در xml ، تگِ پدری ساختیم ، اولا جزء اعضا و کلاس پدر هستند و دوما بتونیم در تگ های فرزندانِ اون پدر (پدر و فرزندی از لحاظ xml) ، در هر کدوم از تگ های اون فرزندان ، مقدار متفاوت و منحصر به فردی به اون پروپرتیِ الحاقی که متعلق به پدر بود ، بدیم . مثل پروپرتیِ Grid.Column که در کد پست 78 که دادین ، هر کدوم از Border ها (که دو تا Border ، فرزند Grid بودن) ، مقدار منحصر به فرد (کلا مقدار جدیدی) به پروپرتیِ الحاقیِ Grid.Column که متعلق به تگ پدر (یعنی کلاس Grid) هست ، میدن .

2) چون این پروپرتی ها متعلق به کلاس و کلا تگ پدر (از لحاظ xml) هستند ، و در تگ فرزندان مقداردهی میشن ، پس وقتی در تگ فرزندان ، چه بصورت attributes و چه بصورت element (از لحاظ xml منظورمه) میخوایم مقداردهی شون کنیم ، چون عملیات ، عملیاتِ مقداردهی کردن هست ، بنابراین داخلِ پروپرتی دیگه نمیشه ریخت .
واسه ی همینه که چه در کد شما (پست 78 که این پروپرتی الحاقی را بصورت attributes مقداردهی کردین) و چه در اون کدی که از اون صفحه در پست 79 دادم (که بصورت المنت (المنت VisualStateManager.VisualStateGroups) مقداردهی کرد) ، توی هیچ کدوم ، اون مقداری که براش در نظر گرفته شد ، داخلِ عضو و پروپرتیِ دیگه ای از اعضای پدر (از لحاظ xml) ، ریخته نمیشه .

درسته؟
------------------------
خوب با این حال ، باز من یه چیز را متوجه نشدم.
الان در کد شما که کد زیر هست :

کد:
        <ControlTemplate x:Key="MyButton" TargetType="{x:Type Button}">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        Grid.Column="0">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
                <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                        Grid.Column="1">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
            </Grid>
        </ControlTemplate>

وقتی عضوِ Grid.Column را در تگ فرزند میخواین مقداردهی کنین ، واضح هست که قبل اش شیِ Grid ای باید به عنوان پدر تعریف بشه تا بتونین به عضوش (یعنی Grid.Column) ، در تگِ فرزندش (یعنی Border) ، دسترسی داشته باشین و مقداردهی اش کنین . که این کار را انجام دادین و قبل از مقداردهیِ Grid.Column در تگِ Border ، تگ Grid را به عنوان پدر ایجاد کردین .
استانداردش هم همینه دیگه . در تعریف پروپرتی الحاقی هم اینه که اصلا باید تگ پدری وجود داشته باشه تا در تگ های فرزندانش بشه پروپرتی های الحاقی پدر را مقداردهی کرد .

حالا چرا در کد زیر (که در پست 79 داده بودم) :

کد:
<ControlTemplate x:Key="roundbutton" TargetType="Button">
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup Name="CommonStates">
                <VisualState Name="Normal">
                </VisualState>
                <VisualState Name="MouseOver">
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</ControlTemplate>

بدون اینکه تگِ پدر را بسازه ، یعنی بدون اینکه بیاد تگِ VisualStateManager را بسازه ، مستقیم رفت تگ VisualStateManager.VisualStateGroups را ساخت و مقداردهی کرد؟
مگه نباید یه همچین کدی شبیه زیر بجای کد بالا مینوشت (که اول تگ پدر را مشخص میکرد) ؟

کد:
<ControlTemplate x:Key="roundbutton" TargetType="Button">
    <Grid>
   
        <VisualStateManager>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup Name="CommonStates">
                <VisualState Name="Normal">
                </VisualState>
                <VisualState Name="MouseOver">
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        </VisualStateManager>
       
    </Grid>
</ControlTemplate>

کلا کد شما و روش بکار بردن و مقداردهی پروپرتی الحاقی تون را متوجه شدم اما این کدی که دادم را متوجه نشدم . توضیح میدین که چرا در اینجا تگ پدر را نساخت؟

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

بعد اینکه VisualState ، همون معادل Trigger هست دیگه؟ (موقع استفاده از ControlTemplate در wpf منظورمه) .
یعنی کار همون ایجاد رویداد را میکنند دیگه .
بنابراین فرقی نداره که از VisualState ها استفاده کنیم یا از Trigger ها .
درسته؟

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

بعد اینکه در کد زیر :

کد:
    <Grid x:Name="myGrid1">
        <Grid.Resources>
            <SolidColorBrush x:Key="MyBrush" Color="Gold"/>

            <Style TargetType="{x:Type Button}" x:Key="PageBackground">
                <Setter Property="Background" Value="Blue"/>
            </Style>

            <ControlTemplate TargetType="{x:Type Button}" x:Key="RoundButton">
                <Grid>
                    <Ellipse Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" MouseEnter="Ellipse_MouseEnter" MouseLeave="Ellipse_MouseLeave"/>
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>

                </Grid>
            </ControlTemplate>

        </Grid.Resources>
    </Grid>

قبلا گفته بودین که برای Key در کد بالا ، بخاطر این پیشوند تعیین میکنن چون این Key ، جزء اعضا و پروپرتیِ خودِ اون المنت (مثلا المنت SolidColorBrush) نیست .
درسته؟
اگه آره ، پس 2 تا سئوال پیش میاد که اولا پس برای پروپرتی Name در Grid که این پروپرتیِ Name جزء اعضای خودِ Grid هست ، پس چرا پیشوند تعیین میشه؟
و دوما در قضیه ی پروپرتی های الحاقی که درون تگ فرزندان مقداردهی میشن و طبعا جزء اعضای کلاس فرزندان نیستند (بلکه جزء اعضای کلاس پدرش هستند) ، چرا پیشوند به پروپرتی های الحاقی ، تعلق نمیگیره؟
خیلی ممنون استاد :rose:
 

the_king

مدیرکل انجمن
آها خیلی ممنون استاد از توضیح کامل تون .
پس attached property ها :
1) پروپرتی هایی هستند که وقتی در xml ، تگِ پدری ساختیم ، اولا جزء اعضا و کلاس پدر هستند و دوما بتونیم در تگ های فرزندانِ اون پدر (پدر و فرزندی از لحاظ xml) ، در هر کدوم از تگ های اون فرزندان ، مقدار متفاوت و منحصر به فردی به اون پروپرتیِ الحاقی که متعلق به پدر بود ، بدیم . مثل پروپرتیِ Grid.Column که در کد پست 78 که دادین ، هر کدوم از Border ها (که دو تا Border ، فرزند Grid بودن) ، مقدار منحصر به فرد (کلا مقدار جدیدی) به پروپرتیِ الحاقیِ Grid.Column که متعلق به تگ پدر (یعنی کلاس Grid) هست ، میدن .
نه. اولی اشتباهه. وقتی میگید اولا فلان یعنی اون فلان الزام آور میشه و باید برقرار باشه. همچین چیزی نیست. مشخصه الحاقی جزو اعضا و کلاس پدر نیست، برای اینکه مشخصه ای مربوط به پدر تعیین بشه بکار میره اما لازم نیست حتما در کلاس پدر باشه. مثلا برای یک المنت FocusManager.IsFocusScope رو مشخص می کنیم ولی FocusManager که جزو المنت ها نیست که حالا پدرش باشه یا نباشه.
و اینکه Column در یک فرزند برای Grid والد مشخص میشه، معنی اش این نیست که پس Column معلق به پدر شه. Grid که Column نداره. ColumnProperty هم لازم نیست حتما جزئی از Grid باشه.
صرفا DependencyProperty ئه، ممکنه هر جایی تعریف شده باشه، مهم اینه که public static ئه، نه در والد بودنش.
ارتباطش با Grid از طریق DependencyProperty ئه که ممکن بود در جای دیگری تعریف شده باشه. اینکه کجا تعریف میشه مهم نیست، مهم اینه که به کدوم صاحبان متصل میشه. ممکن بود اون Column در یک کلاس دیگری جز Grid تعریف شده باشه. مهم اون اتصال مشخصه به Grid ئه، لازم نیست حتما در Grid تعریف شده باشه تا کار کنه. ممکنه اصلا والدی در کار نباشه.

2) چون این پروپرتی ها متعلق به کلاس و کلا تگ پدر (از لحاظ xml) هستند ، و در تگ فرزندان مقداردهی میشن ، پس وقتی در تگ فرزندان ، چه بصورت attributes و چه بصورت element (از لحاظ xml منظورمه) میخوایم مقداردهی شون کنیم ، چون عملیات ، عملیاتِ مقداردهی کردن هست ، بنابراین داخلِ پروپرتی دیگه نمیشه ریخت .
واسه ی همینه که چه در کد شما (پست 78 که این پروپرتی الحاقی را بصورت attributes مقداردهی کردین) و چه در اون کدی که از اون صفحه در پست 79 دادم (که بصورت المنت (المنت VisualStateManager.VisualStateGroups) مقداردهی کرد) ، توی هیچ کدوم ، اون مقداری که براش در نظر گرفته شد ، داخلِ عضو و پروپرتیِ دیگه ای از اعضای پدر (از لحاظ xml) ، ریخته نمیشه .
درسته؟
خیر. فرض اولیه اشتباهه و از نتیجه گیری تون از فرض اشتباه هم چیزی سر در نیاوردم.

بعد اینکه VisualState ، همون معادل Trigger هست دیگه؟ (موقع استفاده از ControlTemplate در wpf منظورمه) .
یعنی کار همون ایجاد رویداد را میکنند دیگه .
بنابراین فرقی نداره که از VisualState ها استفاده کنیم یا از Trigger ها .
درسته؟
VisualState خودش به تنهایی یک وضعیت ئه که ظاهر کنترل رو مشخص می کنه، مثلا Normal برای وضعیت عادی کنترل. اینه که خود VisualState رو نمیشه با Trigger مقایسه کرد.
اون چیزی که مقایسه می کنید VisualStateManager با Trigger ئه. از اساس VisualStateManager برای مشخص کردن ظاهر کنترل بر اساس وضعیت های مشخصی طراحی شده، طبعا برای اینکار وضوح و ساختار بهتری داره تا Trigger.
Trigger یک کارکرد همه منظوره داره و الزاما کاری که باهاش انجام می دهید ربطی به ظاهر کنترل نداره.

قبلا گفته بودین که برای Key در کد بالا ، بخاطر این پیشوند تعیین میکنن چون این Key ، جزء اعضا و پروپرتیِ خودِ اون المنت (مثلا المنت SolidColorBrush) نیست .
درسته؟
اگه آره ، پس 2 تا سئوال پیش میاد که اولا پس برای پروپرتی Name در Grid که این پروپرتیِ Name جزء اعضای خودِ Grid هست ، پس چرا پیشوند تعیین میشه؟
این Name دقیقا اون Name نیست. در اغلب موارد چون مشخصه داخل کنترل همون مقدار رو بکار میبره مقدارشون یکی ئه و بجای هم میشه بکارشون برد اما از اساس x:Name و Name یکی نیستند، اولی از بنیان XAML میاد و دومی از مشخصه Name اون شیء. توضیحات بخش x:Name and Name رو بخونید.

و دوما در قضیه ی پروپرتی های الحاقی که درون تگ فرزندان مقداردهی میشن و طبعا جزء اعضای کلاس فرزندان نیستند (بلکه جزء اعضای کلاس پدرش هستند) ، چرا پیشوند به پروپرتی های الحاقی ، تعلق نمیگیره؟
فرض سوال که اشتباهه، اما اون به کنار، کدوم پیشوند؟ مثلا به فضای نام پیشوند x که تعلق ندارند. از همون فضای نام پیشفرضی میان که مثلا Button میاد. همونطور که x:Button نیست اون مشخصه های الحاقی هم پیشوند نمیخوان.
اینها به همون فضای نام پیشفرض تعلق دارند. طبعا اگر متعلق به فضای نام دیگری بودند پیشوند مربوطه اضافه میشد. می توانید یک پیشوند جدید با همون فضای نام پیشفرض اضافه کنید و ببینید برای همه المنت که پیشوند نداشتند می توانید اون پیشوند جدید خودتون رو بکار ببرید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
نه. اولی اشتباهه. وقتی میگید اولا فلان یعنی اون فلان الزام آور میشه و باید برقرار باشه. همچین چیزی نیست. مشخصه الحاقی جزو اعضا و کلاس پدر نیست، برای اینکه مشخصه ای مربوط به پدر تعیین بشه بکار میره اما لازم نیست حتما در کلاس پدر باشه. مثلا برای یک المنت FocusManager.IsFocusScope رو مشخص می کنیم ولی FocusManager که جزو المنت ها نیست که حالا پدرش باشه یا نباشه.
و اینکه Column در یک فرزند برای Grid والد مشخص میشه، معنی اش این نیست که پس Column معلق به پدر شه. Grid که Column نداره. ColumnProperty هم لازم نیست حتما جزئی از Grid باشه.
صرفا DependencyProperty ئه، ممکنه هر جایی تعریف شده باشه، مهم اینه که public static ئه، نه در والد بودنش.
ارتباطش با Grid از طریق DependencyProperty ئه که ممکن بود در جای دیگری تعریف شده باشه. اینکه کجا تعریف میشه مهم نیست، مهم اینه که به کدوم صاحبان متصل میشه. ممکن بود اون Column در یک کلاس دیگری جز Grid تعریف شده باشه. مهم اون اتصال مشخصه به Grid ئه، لازم نیست حتما در Grid تعریف شده باشه تا کار کنه. ممکنه اصلا والدی در کار نباشه.

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

Column متعلق به Grid نیست؟!!
منظورتون این لینکه؟ :

Grid.Column Attached Property (System.Windows.Controls)

اگه Column متعلق به Grid نیست ، پس متعلق به چی هست؟

خیر. فرض اولیه اشتباهه و از نتیجه گیری تون از فرض اشتباه هم چیزی سر در نیاوردم.

مهمترین بخش سئوالم همین بود :green:
من الان جواب این تیکه از سئوالی که درباره ی اون کد پرسیدم را متوجه نشدم . (سئوالم را دوباره بپرسم) :
حالا چرا در کد زیر (که در پست 79 داده بودم) :

کد:
<ControlTemplate x:Key="roundbutton" TargetType="Button">
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup Name="CommonStates">
                <VisualState Name="Normal">
                </VisualState>
                <VisualState Name="MouseOver">
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</ControlTemplate>

بدون اینکه تگِ پدر را بسازه ، یعنی بدون اینکه بیاد تگِ VisualStateManager را بسازه ، مستقیم رفت تگ VisualStateManager.VisualStateGroups را ساخت و مقداردهی کرد؟

فرض سوال که اشتباهه، اما اون به کنار، کدوم پیشوند؟ مثلا به فضای نام پیشوند x که تعلق ندارند. از همون فضای نام پیشفرضی میان که مثلا Button میاد. همونطور که x:Button نیست اون مشخصه های الحاقی هم پیشوند نمیخوان.
اینها به همون فضای نام پیشفرض تعلق دارند. طبعا اگر متعلق به فضای نام دیگری بودند پیشوند مربوطه اضافه میشد. می توانید یک پیشوند جدید با همون فضای نام پیشفرض اضافه کنید و ببینید برای همه المنت که پیشوند نداشتند می توانید اون پیشوند جدید خودتون رو بکار ببرید.

پس متعلق به فضای نام پیش فرض هستند که پیشوند ندارند .

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

استاد ، من اون موقع فکر میکردم که wpf از لحاظ رسم ، اون قدر دست آدم را باز میذاره که مثلا اگه کنترلی ، پروپرتی ای نداشت ، بشه براش یه پروپرتی جدید در نظر گرفت .
الان انگار متوجه شدم که برای رسم ، باید از همون کلاس هایی استفاده کنیم که شبیه اون را در winform رسم میکردیم .یعنی توی win form که برای رسم مجبور بودیم از کلاس های مختلف و کلاس های مربوط به گرافیک استفاده کنیم تا رسم مون را انجام بدیم ، در wpf هم به همین منوال هست و اساس و بنیان ، فرقی ندارند .
حالا صرفا کلاس ها و کنترل های wpf ، ویژگی و پروپرتی های بیشتری دارند .
بنابراین در wpf برای اینکه رسم های دلخواه مون را انجام بدیم تا یه کنترل شخصی بسازیم ، بهتره از کلاس کلاس های مربوط به Graphic (لینک زیر) هم بهره ببریم . درسته؟ :

Graphics - WPF

خیلی ممنون :rose:
 

the_king

مدیرکل انجمن
Column متعلق به Grid نیست؟!!
منظورتون این لینکه؟ :

Grid.Column Attached Property (System.Windows.Controls)

اگه Column متعلق به Grid نیست ، پس متعلق به چی هست؟
متعلق به هیچی، در #C معادلی نداره که دنبال تعلق اش بگردید. خودتون که در اون لینک می بینید، نه تعریف داره، نه کلاس و نه نوع داده بازگشتی. می بینید که توصیف اش پروتوتایپ #C نداره و فقط ارجاع داده به بخش های دیگه و گفته فلان و بهمان متد و فیلد رو ببینید. وقتی می تونست به چیزی تعلق داشته باشه که در کلاس #C حداقل تعریف اش باشه.
از Object Browser یا نرم افزار هایی که در کد منبع NET. می توانند جستجو کنند استفاده کنید و دنبال Grid.Column بگردید تا ببینید نیست.

مهمترین بخش سئوالم همین بود :green:
من الان جواب این تیکه از سئوالی که درباره ی اون کد پرسیدم را متوجه نشدم . (سئوالم را دوباره بپرسم) :
حالا چرا در کد زیر (که در پست 79 داده بودم) :

کد:
<ControlTemplate x:Key="roundbutton" TargetType="Button">
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup Name="CommonStates">
                <VisualState Name="Normal">
                </VisualState>
                <VisualState Name="MouseOver">
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</ControlTemplate>

بدون اینکه تگِ پدر را بسازه ، یعنی بدون اینکه بیاد تگِ VisualStateManager را بسازه ، مستقیم رفت تگ VisualStateManager.VisualStateGroups را ساخت و مقداردهی کرد؟
به زبان صریح و شیوای فارسی عرض کردم مشخصه الحاقی جزء اعضاء پدر نیست و ممکنه اصلا والدی در کار نباشه.
بعد دوباره می پرسید چرا بدون تگ پدر بسازه فلان کار رو کرد. کدوم پدر؟ سوالی که فرضش اشتباهه که جواب نداره.
من به سوالی که فرضش اشتباهه چه جوابی بدم؟ بگم چون پدرش چند سال پیش تو تصادف رانندگی به رحمت خدا رفته؟

استاد ، من اون موقع فکر میکردم که wpf از لحاظ رسم ، اون قدر دست آدم را باز میذاره که مثلا اگه کنترلی ، پروپرتی ای نداشت ، بشه براش یه پروپرتی جدید در نظر گرفت .
WPF اتفاقا روی همین قضیه تاکید داره که هر کنترلی که لازم دارید با ترکیب سایر اجزاء یا از ابتدا بسازید، کلاس سازی کنید، وراثت ایجاد کنید و هر چقدر هم که خواستید به کلاس هاتون مشخصه اضافه کنید.
شما که دست تون در ساختن کلاس بسته نیست که نتوانید به وارثین مشخصه اضافه کنید. و البته برای طراحی ظاهری ویژوال از Microsoft Blend هم می توانید کمک بگیرید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
متعلق به هیچی، در #C معادلی نداره که دنبال تعلق اش بگردید. خودتون که در اون لینک می بینید، نه تعریف داره، نه کلاس و نه نوع داده بازگشتی. می بینید که توصیف اش پروتوتایپ #C نداره و فقط ارجاع داده به بخش های دیگه و گفته فلان و بهمان متد و فیلد رو ببینید. وقتی می تونست به چیزی تعلق داشته باشه که در کلاس #C حداقل تعریف اش باشه.
از Object Browser یا نرم افزار هایی که در کد منبع NET. می توانند جستجو کنند استفاده کنید و دنبال Grid.Column بگردید تا ببینید نیست.


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

خیلی ممنون استاد .
پس متعلق به هیچ کلاس و عضوی نیستند و واسه ی همین نیاز ندارن که پدری براشون در نظر گرفته بشه .
قضیه ی تصادف هم خیلی خنده دار بود :lol:

WPF اتفاقا روی همین قضیه تاکید داره که هر کنترلی که لازم دارید با ترکیب سایر اجزاء یا از ابتدا بسازید، کلاس سازی کنید، وراثت ایجاد کنید و هر چقدر هم که خواستید به کلاس هاتون مشخصه اضافه کنید.
شما که دست تون در ساختن کلاس بسته نیست که نتوانید به وارثین مشخصه اضافه کنید. و البته برای طراحی ظاهری ویژوال از Microsoft Blend هم می توانید کمک بگیرید.

زودتر Microsoft Blend را معرفی کنین ها :green:
دیشب تا حالا باهاش کار کردم ، در گاهی از حوزه ها ، کار را خیلی راحت تر میکنه .
البته همه ی کارهایی که با Microsoft Blend میشه بصورت رابط کاربری کار کرد ، در ویژال استودیو هم میشه همون کار را منتها با کد نویسی انجام داد دیگه؟
یعنی Microsoft Blend همون کدهای xml را زمانی که با رابط کاربری اش کار میکنیم تولید میکنه که کار را سریعتر انجام میده وگرنه چیزی نداره که نشه توسط کدنویسی در ویژال استودیو ، اون کار را انجام داد .
درسته؟

استاد ، داخل Microsoft Blend ام ، در پنجره ی Assets اش فقط 2 تا کنترل مربوط به shape هست در صورتی که در لینک زیر ، 7 تا کنترل مربوط به shape هست . من چی کار باید کنم تا این کنترل ها را در اونجا اضافه کنم؟ :

Blend for Visual Studio feature tour

همچنین ، نمیشه افکت ها (آبجکت های مربوط به افکت) را در wpf بیشتر کرد؟
کلا فقط 2 تا شی BlurEffect و DropShadowEffect برای افکت ها در wpf وجود داره؟ نمیشه افکت های دیگه ای برای اِعمال روی کنترل ها اضافه کرد؟ اگه میشه ، چجوری میشه؟

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

و اینکه استاد من گشتم ، چیز به درد بخوری درباره ی اینکه چرا پروپرتی Background و BorderBrush در کنترل combobox در wpf ، برام کار نمیکنن ، پیدا نکردم .
حتی با استفاده از استایل SimpleCombobox ، باز هم همینطوره.
ویندوز Windows 10 X64 v1809 دارم و ویژال استودیو 2019 .


و اینکه یه دونه کد بهم دادن (مربوط به استایل و template کنترل combobox که در سایت مایکروسافت هست اما من یه کمی تغییرش دادم) که در بخش آخر پست میذارم . اما چیزی که تعجب من را بر انگیخت اینه که من وقتی مقدار x:Key در تگ Style مربوط به ComboBox را مقدار لیترال دادم (مقدار زیر را دادم) :

کد:
<Style x:Key="ComboboxWithBackgroud" TargetType="ComboBox">

اما وقتی شی کمبوباکسی ساختم که از استایلِ این کمبوباکس استفاده نمیکرد و از استایل SimpleCombobox که استایل پیش فرض wpf هست استفاده میکرد (یعنی کد کمبوباکسم به این صورت بود) :

کد:
        <ComboBox HorizontalAlignment="Left" Height="28" Margin="166,370.606,0,0" Style="{DynamicResource SimpleComboBox}" VerticalAlignment="Top" Width="201.111" SelectedIndex="0" Background="#FF2300FF" BorderBrush="Red">
            <ComboBox.Items>
                <System:String>salam</System:String>
                <System:String>khobi?</System:String>
            </ComboBox.Items>
        </ComboBox>

اما با این حال ، این کمبوباکس ، استایلِ کمبوباکسِ ای که نام key اش را به ComboboxWithBackgroud تغییر داده بودم را به خودش گرفت !
چرا؟!


کد مربوط به استایل و template کنترل combobox که درون Grid.Resources ریختم :

کد:
<LinearGradientBrush x:Key="NormalBrush" StartPoint="0,0" EndPoint="0,1">
                <GradientBrush.GradientStops>
                    <GradientStopCollection>
                        <GradientStop Color="Black" Offset="0.0"/>
                        <GradientStop Color="Red" Offset="1.0"/>
                    </GradientStopCollection>
                </GradientBrush.GradientStops>
            </LinearGradientBrush>
          
            <SolidColorBrush x:Key="WindowBackgroundBrush" Color="DeepSkyBlue" />

            <ControlTemplate x:Key="ComboBoxToggleButton" TargetType="ToggleButton">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition Width="20" />
                    </Grid.ColumnDefinitions>

                    <Border x:Name="Border" Grid.ColumnSpan="2" CornerRadius="2"
  Background="{StaticResource NormalBrush}"
  BorderThickness="1" />
                  
                    <Border
  Grid.Column="0"
  CornerRadius="2,0,0,2"
  Margin="1"
  Background="{StaticResource WindowBackgroundBrush}"
  BorderThickness="0,0,1,0" />
                    <Path
  x:Name="Arrow"
  Grid.Column="1"   
  HorizontalAlignment="Center"
  VerticalAlignment="Center"
  Data="M 0 0 L 4 4 L 8 0 Z" Stroke="Green" StrokeThickness="4"/>
                </Grid>
            </ControlTemplate>

            <ControlTemplate x:Key="ComboBoxTextBox" TargetType="TextBox">
                <Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" />
            </ControlTemplate>


            <Style x:Key="ComboboxWithBackgroud" TargetType="ComboBox">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ComboBox">
                            <Grid>
                                <ToggleButton
         Name="ToggleButton"
         Template="{StaticResource ComboBoxToggleButton}"
         Grid.Column="2"
         Focusable="false"
         IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
         ClickMode="Press">
                                </ToggleButton>
                                <ContentPresenter
        Name="ContentSite"
        IsHitTestVisible="False"
        Margin="3,3,23,3"
        VerticalAlignment="Center"
        HorizontalAlignment="Left" />
                                <TextBox x:Name="PART_EditableTextBox"
         Style="{x:Null}"
         Template="{StaticResource ComboBoxTextBox}"
         HorizontalAlignment="Left"
         VerticalAlignment="Center"
         Margin="3,3,23,3"
         Focusable="True"
         Background="Transparent"
         Visibility="Hidden"
         IsReadOnly="{TemplateBinding IsReadOnly}"/>
                                <Popup
        Name="Popup"
        Placement="Bottom"
        IsOpen="{TemplateBinding IsDropDownOpen}"
        AllowsTransparency="True"
        Focusable="False"
        PopupAnimation="Slide">
                                    <Grid
          Name="DropDown"
          SnapsToDevicePixels="True"              
          MinWidth="{TemplateBinding ActualWidth}"
          MaxHeight="{TemplateBinding MaxDropDownHeight}">
                                        <Border
            x:Name="DropDownBorder"
            Background="{StaticResource WindowBackgroundBrush}"
            BorderThickness="1"/>
                                        <ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
                                            <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
                                        </ScrollViewer>
                                    </Grid>
                                </Popup>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                </Style.Triggers>
            </Style>

خیلی ممنون استاد :rose:
 
آخرین ویرایش:

the_king

مدیرکل انجمن
خیلی ممنون استاد .
پس متعلق به هیچ کلاس و عضوی نیستند و واسه ی همین نیاز ندارن که پدری براشون در نظر گرفته بشه .
قضیه ی تصادف هم خیلی خنده دار بود :lol:



زودتر Microsoft Blend را معرفی کنین ها :green:
دیشب تا حالا باهاش کار کردم ، در گاهی از حوزه ها ، کار را خیلی راحت تر میکنه .
البته همه ی کارهایی که با Microsoft Blend میشه بصورت رابط کاربری کار کرد ، در ویژال استودیو هم میشه همون کار را منتها با کد نویسی انجام داد دیگه؟
یعنی Microsoft Blend همون کدهای xml را زمانی که با رابط کاربری اش کار میکنیم تولید میکنه که کار را سریعتر انجام میده وگرنه چیزی نداره که نشه توسط کدنویسی در ویژال استودیو ، اون کار را انجام داد .
درسته؟
قطعا همینطوره.

استاد ، داخل Microsoft Blend ام ، در پنجره ی Assets اش فقط 2 تا کنترل مربوط به shape هست در صورتی که در لینک زیر ، 7 تا کنترل مربوط به shape هست . من چی کار باید کنم تا این کنترل ها را در اونجا اضافه کنم؟ :

Blend for Visual Studio feature tour

همچنین ، نمیشه افکت ها (آبجکت های مربوط به افکت) را در wpf بیشتر کرد؟
کلا فقط 2 تا شی BlurEffect و DropShadowEffect برای افکت ها در wpf وجود داره؟ نمیشه افکت های دیگه ای برای اِعمال روی کنترل ها اضافه کرد؟ اگه میشه ، چجوری میشه؟
در مورد Blend از من سوال نپرسید، من طراح Blend کار نیستم.
Missing drawing assets polygons, paths, polyline and lines in Shapes Asset window

و اینکه استاد من گشتم ، چیز به درد بخوری درباره ی اینکه چرا پروپرتی Background و BorderBrush در کنترل combobox در wpf ، برام کار نمیکنن ، پیدا نکردم .
حتی با استفاده از استایل SimpleCombobox ، باز هم همینطوره.
ویندوز Windows 10 X64 v1809 دارم و ویژال استودیو 2019 .
میتونه باگ باشه یا یک دستکاری مختصری که خودتون در کدی دادید و تداخل ایجاد می کنه. اما در کل این رو میدونم که Designer ویژوال استدیو در نمایش WPF با تغییر همه مشخصه ها ظاهر رو بروز نمی کنه و مورد جدیدی نیست. قاعدتا باگ محسوب میشه اما اگه عمدا و با دلیل خاصی بوده اطلاعی ندارم. اینکه در عملکرد ویژوال استدیو یا کنترل هاش باگ ای پیدا کنید خیلی عجیب نیست، بعضی هاش مربوط به نسخه خاصی هستند که در نسخه های بعدی رفع میشوند و بعضی ها هم همیشه اون باگ شناخته شده براشون میمونه.

و اینکه یه دونه کد بهم دادن (مربوط به استایل و template کنترل combobox که در سایت مایکروسافت هست اما من یه کمی تغییرش دادم) که در بخش آخر پست میذارم . اما چیزی که تعجب من را بر انگیخت اینه که من وقتی مقدار x:Key در تگ Style مربوط به ComboBox را مقدار لیترال دادم (مقدار زیر را دادم) :

کد:
<Style x:Key="ComboboxWithBackgroud" TargetType="ComboBox">

اما وقتی شی کمبوباکسی ساختم که از استایلِ این کمبوباکس استفاده نمیکرد و از استایل SimpleCombobox که استایل پیش فرض wpf هست استفاده میکرد (یعنی کد کمبوباکسم به این صورت بود) :
اما با این حال ، این کمبوباکس ، استایلِ کمبوباکسِ ای که نام key اش را به ComboboxWithBackgroud تغییر داده بودم را به خودش گرفت !
چرا؟!
من از کد های پخش و پلایی که قرار دادید چیزی سر در نیاوردم. معلوم نیست چی رو کجا نوشتید. یک کد کامل XAML لازمه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
میتونه باگ باشه یا یک دستکاری مختصری که خودتون در کدی دادید و تداخل ایجاد می کنه. اما در کل این رو میدونم که Designer ویژوال استدیو در نمایش WPF با تغییر همه مشخصه ها ظاهر رو بروز نمی کنه و مورد جدیدی نیست. قاعدتا باگ محسوب میشه اما اگه عمدا و با دلیل خاصی بوده اطلاعی ندارم. اینکه در عملکرد ویژوال استدیو یا کنترل هاش باگ ای پیدا کنید خیلی عجیب نیست، بعضی هاش مربوط به نسخه خاصی هستند که در نسخه های بعدی رفع میشوند و بعضی ها هم همیشه اون باگ شناخته شده براشون میمونه.

خیلی ممنون استاد (همچنین از جواب بقیه ی قسمت ها) .
از یکی دیگه هم خبر گرفتم گفت که واسه ی اون هم همینطوره .

من از کد های پخش و پلایی که قرار دادید چیزی سر در نیاوردم. معلوم نیست چی رو کجا نوشتید. یک کد کامل XAML لازمه.

کد کاملش اینه :

کد:
<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPF_Practice"
        xmlns:System="clr-namespace:System;assembly=mscorlib" x:Class="WPF_Practice.Window1"
        mc:Ignorable="d"
        Title="Window1" Height="450" Width="800">

    <Grid x:Name="myGrid1">

        <!-- Grid Resources -->
        <Grid.Resources>

            <LinearGradientBrush x:Key="NormalBrush" StartPoint="0,0" EndPoint="0,1">
                <GradientBrush.GradientStops>
                    <GradientStopCollection>
                        <GradientStop Color="Black" Offset="0.0"/>
                        <GradientStop Color="Red" Offset="1.0"/>
                    </GradientStopCollection>
                </GradientBrush.GradientStops>
            </LinearGradientBrush>

            <SolidColorBrush x:Key="WindowBackgroundBrush" Color="DeepSkyBlue" />

            <ControlTemplate x:Key="ComboBoxToggleButton" TargetType="ToggleButton">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition Width="20" />
                    </Grid.ColumnDefinitions>

                    <Border x:Name="Border" Grid.ColumnSpan="2" CornerRadius="2"
  Background="{StaticResource NormalBrush}"
  BorderThickness="1" />

                    <Border
  Grid.Column="0"
  CornerRadius="2,0,0,2"
  Margin="1"
  Background="{StaticResource WindowBackgroundBrush}"
  BorderThickness="0,0,1,0" />
                    <Path
  x:Name="Arrow"
  Grid.Column="1"    
  HorizontalAlignment="Center"
  VerticalAlignment="Center"
  Data="M 0 0 L 4 4 L 8 0 Z" Stroke="Green" StrokeThickness="4"/>
                </Grid>
            </ControlTemplate>

            <ControlTemplate x:Key="ComboBoxTextBox" TargetType="TextBox">
                <Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" />
            </ControlTemplate>


            <Style x:Key="ComboboxWithBackgroud" TargetType="ComboBox">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ComboBox">
                            <Grid>
                                <ToggleButton
         Name="ToggleButton"
         Template="{StaticResource ComboBoxToggleButton}"
         Grid.Column="2"
         Focusable="false"
         IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
         ClickMode="Press">
                                </ToggleButton>
                                <ContentPresenter
        Name="ContentSite"
        IsHitTestVisible="False"
        Margin="3,3,23,3"
        VerticalAlignment="Center"
        HorizontalAlignment="Left" />
                                <TextBox x:Name="PART_EditableTextBox"
         Style="{x:Null}"
         Template="{StaticResource ComboBoxTextBox}"
         HorizontalAlignment="Left"
         VerticalAlignment="Center"
         Margin="3,3,23,3"
         Focusable="True"
         Background="Transparent"
         Visibility="Hidden"
         IsReadOnly="{TemplateBinding IsReadOnly}"/>
                                <Popup
        Name="Popup"
        Placement="Bottom"
        IsOpen="{TemplateBinding IsDropDownOpen}"
        AllowsTransparency="True"
        Focusable="False"
        PopupAnimation="Slide">
                                    <Grid
          Name="DropDown"
          SnapsToDevicePixels="True"               
          MinWidth="{TemplateBinding ActualWidth}"
          MaxHeight="{TemplateBinding MaxDropDownHeight}">
                                        <Border
            x:Name="DropDownBorder"
            Background="{StaticResource WindowBackgroundBrush}"
            BorderThickness="1"/>
                                        <ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
                                            <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
                                        </ScrollViewer>
                                    </Grid>
                                </Popup>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                </Style.Triggers>
            </Style>


        </Grid.Resources>




        <!-- Grid Contents -->
        <ComboBox HorizontalAlignment="Left" Height="28" Margin="120,121,0,0" Style="{DynamicResource SimpleComboBox}" VerticalAlignment="Top" Width="202" SelectedIndex="0" Background="#FF2300FF" BorderBrush="Red">
            <ComboBox.Items>
                <System:String>salam</System:String>
                <System:String>khobi?</System:String>
            </ComboBox.Items>
        </ComboBox>

    </Grid>


</Window>
 

the_king

مدیرکل انجمن
اولا در کدی که قرار دادید {DynamicResource SimpleComboBox} تعریف نمیشه و در نتیجه نوشتن و ننوشتنش تاثیری نداره.
از طرف دیگه ComboBox تون هم طوری که توصیف کردید نیست، لااقل من چیزی متفاوت از توصیف شما رو می بینم.
از Style ای که با نام ComboboxWithBackgroud تعریف کردید استفاده نمیکنه، وقتی می توانست برایش Style پیشفرض باشه که شما Style رو بدون Key تعریف می کردید که در اون صورت شامل تمامی ComboBox هایی که Style شون صریحا مشخص نشده میشد. از اونجایی که شما ComboboxWithBackgroud رو با Key نامگذاری کردید دیگه Style پیشفرض نیست.
نه در هنگام طراحی و نه در هنگام اجرا همچین چیزی رو نمی بینم که ComboBox ئه از ComboboxWithBackgroud استفاده کرده باشه.
نمیدونم چرا میگید از اون ComboboxWithBackgroud استفاده کرده.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
اولا در کدی که قرار دادید {DynamicResource SimpleComboBox} تعریف نمیشه و در نتیجه نوشتن و ننوشتنش تاثیری نداره.
از طرف دیگه ComboBox تون هم طوری که توصیف کردید نیست، لااقل من چیزی متفاوت از توصیف شما رو می بینم.
از Style ای که با نام ComboboxWithBackgroud تعریف کردید استفاده نمیکنه، وقتی می توانست برایش Style پیشفرض باشه که شما Style رو بدون Key تعریف می کردید که در اون صورت شامل تمامی ComboBox هایی که Style شون صریحا مشخص نشده میشد. از اونجایی که شما ComboboxWithBackgroud رو با Key نامگذاری کردید دیگه Style پیشفرض نیست.
نه در هنگام طراحی و نه در هنگام اجرا همچین چیزی رو نمی بینم که ComboBox ئه از ComboboxWithBackgroud استفاده کرده باشه.
نمیدونم چرا میگید از اون ComboboxWithBackgroud استفاده کرده.

خیلی ممنون استاد
استایل SimpleComboBox ، درون خود wpf ، در فایل جداگانه تعریف شده . حالا باز هم من کدش را کپی میکنم و در منبع grid ام قرار میدم .
کدها چون زیاد هستن و نمیشه پست ارسال کرد ، در فایل txt ریختم و آپلود کردم .
الان کد در فایل بنام 1.txt ، استایلی که شی کمبوباکس تون داره ، چیه؟
استایل ComboboxWithBackground نیست؟ (با اونکه توی شی کمبوباکس ، استایل SimpleCombobox مشخص شده) .
واسه ی من که با این حال ، استایل ComboboxWithBackground را داره .


بعد ، کدی که در فایل 2.txt گذاشتم را چک کنید . در این فایل ، فقط استایل SimpleComboBox مونده و استایل ComboboxWithBackground حذف شده .
در کد فایل 2.txt ، میبینید که وقتی فقط استایل SimpleComboBox هست ، حالا شی کمبوباکس مون ، این استایل را به خودش میگیره .
متوجه ی منظورم شدین؟
 

پیوست ها

  • 1.txt
    9.9 کیلوبایت · بازدیدها: 2
  • 2.txt
    5.8 کیلوبایت · بازدیدها: 1

the_king

مدیرکل انجمن
خیلی ممنون استاد
استایل SimpleComboBox ، درون خود wpf ، در فایل جداگانه تعریف شده . حالا باز هم من کدش را کپی میکنم و در منبع grid ام قرار میدم .
کدها چون زیاد هستن و نمیشه پست ارسال کرد ، در فایل txt ریختم و آپلود کردم .
الان کد در فایل بنام 1.txt ، استایلی که شی کمبوباکس تون داره ، چیه؟
استایل ComboboxWithBackground نیست؟ (با اونکه توی شی کمبوباکس ، استایل SimpleCombobox مشخص شده) .
واسه ی من که با این حال ، استایل ComboboxWithBackground را داره .
استایلش همون SimpleComboBox ئه دیگه. مثلا در SimpleComboBox گفتید ToggleButton اش ComboBoxToggleButton باشه، و در ComboBoxToggleButton گفتید زمینه ToggleButton ئه NormalBrush باشه، در تعریف NormalBrush هم گفتید طیف Black Red باشه. خوب در ظاهر ComboBox ئه همون طیف Black Red شده دیگه. من مورد غیر عادی ای نمی بینم.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
استایلش همون SimpleComboBox ئه دیگه. مثلا در SimpleComboBox گفتید ToggleButton اش ComboBoxToggleButton باشه، و در ComboBoxToggleButton گفتید زمینه ToggleButton ئه NormalBrush باشه، در تعریف NormalBrush هم گفتید طیف Black Red باشه. خوب در ظاهر ComboBox ئه همون طیف Black Red شده دیگه. من مورد غیر عادی ای نمی بینم.

خیلی ممنون .
شما هر دو تا کد را ببینید .
هر دو کد (یعنی کد در فایل 1.txt و فایل 2.txt) برای شما ، از لحاظ ظاهری ، فرقی نداره؟
هر دو کمبوباکس در دو کد ، یک شکل هستن؟
 

the_king

مدیرکل انجمن
خیلی ممنون .
شما هر دو تا کد را ببینید .
هر دو کد (یعنی کد در فایل 1.txt و فایل 2.txt) برای شما ، از لحاظ ظاهری ، فرقی نداره؟
هر دو کمبوباکس در دو کد ، یک شکل هستن؟
نه. خیلی فرق داره، در ‎2.txt شما یک Style ناقص و ایراد دار ساخته اید که درست کار نمی کنه. طبعا Style ای که ناقص باشه با Style کامل ظاهر متفاوتی داره.
شما فرضا نوشته اید {DynamicResource ComboBoxToggleButton} در حالی که هیچ Resource ای با نام ComboBoxToggleButton تعریف نکرده اید و WPF نمیتونه پیداش کنه.
ظاهر Template چطور از حالت پیشفرض متفاوت باشه وقتی Template مورد نظر تعریف نشده.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
نه. خیلی فرق داره، در ‎2.txt شما یک Style ناقص و ایراد دار ساخته اید که درست کار نمی کنه. طبعا Style ای که ناقص باشه با Style کامل ظاهر متفاوتی داره.
شما فرضا نوشته اید {DynamicResource ComboBoxToggleButton} در حالی که هیچ Resource ای با نام ComboBoxToggleButton تعریف نکرده اید و WPF نمیتونه پیداش کنه.
ظاهر Template چطور از حالت پیشفرض متفاوت باشه وقتی Template مورد نظر تعریف نشده.

خیلی ممنون استاد .
فایل شماره 2 کار نمیکنه؟!
واسه ی من بدون مشکل کار میکنه . نه ارور میده و نه چیز دیگه ای . تصویرش هم اینه :

1.JPG

کد من نیست . هر دو ، کد مایکروسافت هستن . template هایی که مایکروسافت کدش را گذاشت .
کد فایل اولی را هم که اجرا میکنم ، استایل کمبوباکس این جوری میشه :
2.JPG

کد فایل 2 هم که شکل اش در بالا هست . (اینها در صورتی اند که هر دو شیِ کمبوباکس مون از استایل SimpleCombobox استفاده میکنه که این استایل ، key ثابت ای با همین مقدار داره که در کدها میبینین) .
الان منظورتون اینه که مشکلِ اینکه ، در هر دو کد ، با اونکه از یک استایل (استایل Simple Template) استفاده میشه اما شکل ها متفاوت هستند ، بخاطر کد {DynamicResource ComboBoxToggleButton} هست؟
کلا مشکلش از کجاست؟
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
فایل شماره 2 کار نمیکنه؟!
واسه ی من بدون مشکل کار میکنه . نه ارور میده و نه چیز دیگه ای . تصویرش هم اینه :

مشاهده پیوست 113410
کد برنامه اجرایی نیست که ارور بده. مثل اشکال در کد HTML صفحات وب یا کد های BBCode در همین پست های داخل فروم میمونه که فرضا تگ پایانی چیزی از قلم بیافته و بخاطرش یک چیزی درست نشون داده نمیشه.

کد من نیست . هر دو ، کد مایکروسافت هستن . template هایی که مایکروسافت کدش را گذاشت .
ممکنه برای آموزش یک موضوعی بخش های نامربوط قرار داده نشه، الزاما کد کامل نیست. فرض بر اینه که خواننده تفاوت یک مثال با یک کد کامل رو میدونه، مثلا در How to: Create Event Handlers at Run Time for Windows Forms کدی که مایکروسافت قرار داده کد کاملی که نیست.

کد فایل اولی را هم که اجرا میکنم ، استایل کمبوباکس این جوری میشه :
مشاهده پیوست 113412

کد فایل 2 هم که شکل اش در بالا هست . (اینها در صورتی اند که هر دو شیِ کمبوباکس مون از استایل SimpleCombobox استفاده میکنه که این استایل ، key ثابت ای با همین مقدار داره که در کدها میبینین) .
الان منظورتون اینه که مشکلِ اینکه ، در هر دو کد ، با اونکه از یک استایل (استایل Simple Template) استفاده میشه اما شکل ها متفاوت هستند ، بخاطر کد {DynamicResource ComboBoxToggleButton} هست؟
کلا مشکلش از کجاست؟
کاری نداره، سطر به سطر برای خودتون تفسیرش کنید. مشکل خیلی بدیهی ئه، Style ئه چیزی نیست جز دو تا Setter. اون Setter اول که هیچی، یک bool ساده است. اما دومی که ControlTemplate ئه رو تفسیر کنید. همون اول در Grid اش میگید من یک ToggleButton میخوام با Template ئه {DynamicResource ComboBoxToggleButton}. کجاست این Resource با نام ComboBoxToggleButton؟ کجا تعریفش کردید؟
بعد میگید یک TextBox میخوام با Template ئه {DynamicResource ComboBoxTextBox}. تعریف ComboBoxTextBox در کدوم قسمت از این کد ئه؟
ظاهر داخل اون Template ها تعریف شده بوده که چون تعریفش نیست بی تاثیر شده. خوب بدیهیه که وقتی دو تا کد کامل و ناقص مقایسه می شوند ظاهر فایل ‎1.txt و ‎2.txt فرق می کنه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
کاری نداره، سطر به سطر برای خودتون تفسیرش کنید. مشکل خیلی بدیهی ئه، Style ئه چیزی نیست جز دو تا Setter. اون Setter اول که هیچی، یک bool ساده است. اما دومی که ControlTemplate ئه رو تفسیر کنید. همون اول در Grid اش میگید من یک ToggleButton میخوام با Template ئه {DynamicResource ComboBoxToggleButton}. کجاست این Resource با نام ComboBoxToggleButton؟ کجا تعریفش کردید؟
بعد میگید یک TextBox میخوام با Template ئه {DynamicResource ComboBoxTextBox}. تعریف ComboBoxTextBox در کدوم قسمت از این کد ئه؟
ظاهر داخل اون Template ها تعریف شده بوده که چون تعریفش نیست بی تاثیر شده. خوب بدیهیه که وقتی دو تا کد کامل و ناقص مقایسه می شوند ظاهر فایل ‎1.txt و ‎2.txt فرق می کنه.

خیلی ممنون استاد . :rose:
بله درست گفتید .
انگار چون هر دو کد را مایکروسافت ساخته بود ، وقتی کدهای این Resource هایی که گفتید را توی Grid.resource ام کپی کردم ، نام چند تاشون با همدیگه یکی بود و بنابراین چون تا قبل از اینکه شما بگید ، اون منابع را کپی نکردم ، از اون یکی منبعی که نامش باهاش یکی بود ، استفاده میکرد .
کلا مشکل تداخل نام های یکسان منابع در دو کد بود . (البته به احتمال زیاد) .
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلامی مجدد
استاد ، میخوام یه textbox ای طراحی کنم که border نداشته باشه . کدی که در مایکروسافت هست را گرفتم که اینه و درست کار میکنه :

کد:
<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPF_Practice"
        xmlns:System="clr-namespace:System;assembly=mscorlib" x:Class="WPF_Practice.Window1"
        mc:Ignorable="d"
        Title="Window1" Height="450" Width="800">

    <Window.Resources>
        <Color x:Key="ContentAreaColorDark">#FF7381F9</Color>

        <Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
        <Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
        <Color x:Key="ControlLightColor">White</Color>

    </Window.Resources>

    <Grid x:Name="myGrid1">

        <!-- Grid Resources -->
        <Grid.Resources>

            <Style x:Key="TextBoxMicrosoft" TargetType="{x:Type TextBox}">
                <Setter Property="SnapsToDevicePixels"
          Value="True" />
                <Setter Property="OverridesDefaultStyle"
          Value="True" />
                <Setter Property="KeyboardNavigation.TabNavigation"
          Value="None" />
                <Setter Property="FocusVisualStyle"
          Value="{x:Null}" />
                <Setter Property="MinWidth"
          Value="120" />
                <Setter Property="MinHeight"
          Value="20" />
                <Setter Property="AllowDrop"
          Value="true" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type TextBoxBase}">
                            <Border Name="Border"
                CornerRadius="2"
                Padding="2"
                BorderThickness="1">
                                <Border.Background>
                                    <SolidColorBrush Color="{DynamicResource ControlLightColor}" />
                                </Border.Background>
                                <Border.BorderBrush>
                                    <SolidColorBrush Color="{DynamicResource ContentAreaColorDark}" />
                                </Border.BorderBrush>
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="Normal" />
                                        <VisualState x:Name="Disabled">
                                            <Storyboard>
                                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                Storyboard.TargetProperty="(Panel.Background).
                    (SolidColorBrush.Color)">
                                                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource DisabledControlLightColor}" />
                                                </ColorAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="ReadOnly">
                                            <Storyboard>
                                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                Storyboard.TargetProperty="(Panel.Background).
                    (SolidColorBrush.Color)">
                                                    <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource DisabledControlDarkColor}" />
                                                </ColorAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="MouseOver" />
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                                <ScrollViewer Margin="0"
                        x:Name="PART_ContentHost" />
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

        </Grid.Resources>
        <TextBox Style="{StaticResource TextBoxMicrosoft}" HorizontalAlignment="Left" Height="40" Margin="10,119,0,0" TextWrapping="Wrap" Text="my text box 1" VerticalAlignment="Top" Width="234"/>

    </Grid>


</Window>

اما خودم که خواستم کدها را از اول بنویسم ، برام اون قسمتی که میخوام متنِ داخلِ textbox را ویرایش کنم (اضافه یا کم یا کلا چیز جدیدی بنویسم) ، کار نمیکنه :

کد:
    <Grid x:Name="myGrid1">

        <!-- Grid Resources -->
        <Grid.Resources>
            <!-- TextBox Template -->
            <ControlTemplate x:Key="TextBoxPracties" TargetType="TextBox">
                <Grid>
                    <ContentPresenter Content="{TemplateBinding Text}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Grid>
            </ControlTemplate>
        </Grid.Resources>

        <TextBox Template="{StaticResource TextBoxPracties}" HorizontalAlignment="Left" Height="40" Margin="10,119,0,0" TextWrapping="Wrap" Text="my text box 1" VerticalAlignment="Top" Width="234"/>

    </Grid>

کدوم بخش از کدهای مایکروسافت ، باعث میشه تا بشه متن داخل لیست باکس اش را تغییر داد؟
بعد اینکه من توی چیزهای کلی ای که برای ساخت کنترل ها لازم هست ، آشنایی ندارم . مثل همین قضیه که نمیدونم برای ویرایش متن داخل تکست باکس ، باید چه کار کرد . یا مثلا برای ساخت یه کمبوباکس ، دقیق نمیدونم برای کلیت کارش ، چه اشیاها و کارهایی لازم هست و ... . متوجه ی منظورم شدین؟ منظورم جزئیات کار نیست . کلیات کار و اشیا و تنظیماتی که لازم هست ، مد نظرمه .
حالا برای این قضیه ، آیا راهنمایی برای کلیات کار هست؟
که مثلا بگه بصورت کلی ، مثلا برای ساخت یک تکست باکس ، باید برای قابلیت ویرایش متن ، این کار انجام بشه . یا برای کمبوباکس ، از ترکیبی از کنترل togglebutton و popup استفاده کرد . یا همینطور برای کنترل های دیگه .
اصلا مگه با تغییر template یک کنترل (مثل تکست باکس) ، ماهیت اش که تغییر دادن متن داخل تکست باکس هست ، عوض میشه؟!
ماهیت اش نباید عوض بشه . درسته؟

استاد ، تعداد کاراکترهای هر پست در انجمن را افزایش میدین؟ هر پست ، محدود به 10000 کاراکتر هست اما کدهای xml خیلی کاراکترهای زیادی دارند و بنابراین ارسال شون در انجمن ، با مشکل مواجه میشه .
خیلی ممنون
 

the_king

مدیرکل انجمن
سلامی مجدد
اما خودم که خواستم کدها را از اول بنویسم ، برام اون قسمتی که میخوام متنِ داخلِ textbox را ویرایش کنم (اضافه یا کم یا کلا چیز جدیدی بنویسم) ، کار نمیکنه :

کد:
    <Grid x:Name="myGrid1">

        <!-- Grid Resources -->
        <Grid.Resources>
            <!-- TextBox Template -->
            <ControlTemplate x:Key="TextBoxPracties" TargetType="TextBox">
                <Grid>
                    <ContentPresenter Content="{TemplateBinding Text}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Grid>
            </ControlTemplate>
        </Grid.Resources>

        <TextBox Template="{StaticResource TextBoxPracties}" HorizontalAlignment="Left" Height="40" Margin="10,119,0,0" TextWrapping="Wrap" Text="my text box 1" VerticalAlignment="Top" Width="234"/>

    </Grid>
برای اینکه یاد بگیرید چشم بسته کد رو Copy / Paste نکنید. سطر به سطر تفسیرش کنید تا ببینید چه توصیفی می کنه. البته می توانستید در یک Style و با یک Setter صرفا مقدار BorderThickness رو 0 کنید و لزومی نداشت ControlTemplate جدید بسازید. در ضمن با TextBox مثل یک ContentControl رفتار کردید و برای کنترلی که ContentControl نبوده ContentPresenter تعریف کردید، خوب اونم تبدیل شده به یک چیزی بین TextBox و Label. چه چیزی در کد به نظرتون عجیبه؟

کدوم بخش از کدهای مایکروسافت ، باعث میشه تا بشه متن داخل لیست باکس اش را تغییر داد؟
متن داخل ListBox؟ ListBoxItem های داخلش. اگه منظورتون TextBox ئه خوب Text.

بعد اینکه من توی چیزهای کلی ای که برای ساخت کنترل ها لازم هست ، آشنایی ندارم . مثل همین قضیه که نمیدونم برای ویرایش متن داخل تکست باکس ، باید چه کار کرد . یا مثلا برای ساخت یه کمبوباکس ، دقیق نمیدونم برای کلیت کارش ، چه اشیاها و کارهایی لازم هست و ... . متوجه ی منظورم شدین؟ منظورم جزئیات کار نیست . کلیات کار و اشیا و تنظیماتی که لازم هست ، مد نظرمه .
حالا برای این قضیه ، آیا راهنمایی برای کلیات کار هست؟
متن داخل TextBox داخل Text قرار داره، طبعا اگر می خواهیم Text رو ویرایش کنیم مشخصه Text رو ویرایش می کنیم :
کد:
<TextBox Text="Sample"/>
یا :
کد:
            <TextBox>
                <TextBox.Style>
                    <Style TargetType="TextBox">
                        <Setter Property="Text" Value="Sample"/>
                    </Style>
                </TextBox.Style>
            </TextBox>
برای ساختن ComboBox اول Style و Template اش رو مطالعه می کنید تا ببینید اجزاء اش چیه.

که مثلا بگه بصورت کلی ، مثلا برای ساخت یک تکست باکس ، باید برای قابلیت ویرایش متن ، این کار انجام بشه . یا برای کمبوباکس ، از ترکیبی از کنترل togglebutton و popup استفاده کرد . یا همینطور برای کنترل های دیگه .
اصلا مگه با تغییر template یک کنترل (مثل تکست باکس) ، ماهیت اش که تغییر دادن متن داخل تکست باکس هست ، عوض میشه؟!
ماهیت اش نباید عوض بشه . درسته؟
نمیدونم ماهیت رو چی تعریف می کنید اما مثلا بصورت پیشفرض متن داخل TextBox خودش جداگانه ویرایش میشه، یعنی در کلاسش تعریفش شده که فرضا وقتی با صفحه کلید تایپ می کنید Text اش تغییر کنه، حتی اگه ظاهرش رو تغییر بدید. اما اینکه شما در ظاهر کنترل چی نمایش بدید طبعا روی عملکردش تاثیر میذاره :
کد:
                <ControlTemplate TargetType="TextBox" x:Key="MyTextBox">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition Width="30"/>
                        </Grid.ColumnDefinitions>
                        <ScrollViewer Margin="0" x:Name="PART_ContentHost" VerticalAlignment="Center"/>
                        <Border BorderBrush="{x:Static SystemColors.WindowFrameBrush}" BorderThickness="1" Grid.Column="0"/>
                        <Button Content="..." Grid.Column="1" Focusable="False"/>
                    </Grid>
                </ControlTemplate>
اون ScrollViewer بخشی است که متن داخلش نوشته میشه، فرضا اگه با یک TextBlock که Text اش Bind شده به Text کنترل تعویض اش کنید دیگه از چشمکزن و تغییرات ظاهری پیمایش TextBox خبری نیست.

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

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

بالا