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

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
کد Template مشابه رو دیگه برای چی کپی کنید؟

در پست قبلی که گفته بودم DynamicResource را نمیذاره برای پروپرتی Value ئه Setter ، سِت کنیم .
خوب؟
بخاطر همین پس باید از StaticResource استفاده کنم .
از StaticResource هم استفاده کنم ، منابعی که توسط StaticResource در تمپلیت و استایل تعریف شد ، باید در خطِ بالاتر و قبل از اینکه StaticResource فراخونی بشه ، منبع مورد نظرش در Resource ایجاد شده باشه که میدونید .

در کد و روشی که دادید ، باید جوری بچینم که Template ها ، بعد از Brush ها و استایل ها تعریف بشن .
خوب ، تنها جایی که میمونه ، در همون بخشِ کدِ Style ئه مربوطه (مثلا در DarkStyle) و در قسمت آخر باید این Template ها را تعریف کنم که با این شیوه بخوام پیش برم ، من که چاره ای جز کپی کردنِ دوباره ی Template ها پیدا نکردم .

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


تشکر استاد .
 

پیوست ها

  • StyleResource.rar
    4.6 کیلوبایت · بازدیدها: 2
آخرین ویرایش:

the_king

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

اما DynamicResource ، نسبت به StaticResource ، منابع سخت افزاری بیشتری را درگیر نمیکنه؟
DynamicResource خودش کاری نمی کنه، پروژه شما سربار ایجاد می کنه و میزان سربار هم بر اساس اجرای پروژه تون مشخص میشه.
منبع پویا یعنی تغییر میکنه، اینکه چقدر تغییر می کنه یا چند بار به منبع رجوع میشه رو که DynamicResource تعیین نمی کنه، شما در پروژه تون تعیین اش می کنید، ربطی به DynamicResource نداره که میزان سربار اش رو DynamicResource مشخص کنه. میزان سربار به تعدد استفاده و میزان رجوع و میزان تغییرات وابسته است که خصوصیات پروژه شما است، در هر پروژه ای هم فرق می کنه. در کل درصدش به مشخصات پروژه شما وابسته است، نه DynamicResourc .
با StaticResource هم نمیشه مقایسه کرد. در StaticResource تغییر مقدار منبع یا رجوع مجدد تاثیری نداره که با اون مقایسه اش کنید. معادل هم نیستند که در شرایط یکسان بجای هم قابل استفاده باشن. کارکرد متفاوتی دارند.

اگه آره ، تا حدودا چقدر درگیر میکنه؟ و چند درصد در کاهش کارایی و سرعت برنامه مون تاثیر میذاره؟
نمیشه کلی مقایسه کرد، منبع پویا و ایستا دو تا کارکرد متفاوت دارند. معادل هم نیستند که بتوانید کارایی شون رو با هم مقایسه کنید.

راستی استاد ، DynamicResource را نمیذاره برای پروپرتی Value ئه Setter ، سِت کنیم .
در پست 321# مقدار {DynamicResource checkBoxCustTemplate} رو در Setter قرار دادم، نمونه مشابه اش در کد شما هم هست، اگر ایراد اساسی بود که اونجا هم باید عملی نمیشد. نمیشه نتیجه گرفت که چون جایی منطق کدتون ایراد داره و به DynamicResource ایراد گرفته، پس DynamicResource نمیتونه به عنوان Value در Setter مشخص بشه. قبلا در مورد زمانبندی و ترتیب صحیح اینکار صحبت کردیم. یا تلاش به دسترسی به منبع خارج از محدوده بوده یا زمانی به منبع رجوع شده که هنوز فراخوانی نشده. یعنی ترتیب درست در منطق کدتون رعایت نشده.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
در پست 321# مقدار {DynamicResource checkBoxCustTemplate} رو در Setter قرار دادم، نمونه مشابه اش در کد شما هم هست، اگر ایراد اساسی بود که اونجا هم باید عملی نمیشد. نمیشه نتیجه گرفت که چون جایی منطق کدتون ایراد داره و به DynamicResource ایراد گرفته، پس DynamicResource نمیتونه به عنوان Value در Setter مشخص بشه. قبلا در مورد زمانبندی و ترتیب صحیح اینکار صحبت کردیم. یا تلاش به دسترسی به منبع خارج از محدوده بوده یا زمانی به منبع رجوع شده که هنوز فراخوانی نشده. یعنی ترتیب درست در منطق کدتون رعایت نشده.

خیلی ممنون استاد (همچنین برای جواب بقیه ی قسمت ها)
من هم قاتی کردم . بله جاهایی شده که در Value ئه Setter ، از DynamicResource استفاده کردم و مشکلی نگرفت .
درباره ی ترتیب اجرا میدونم ولی اگه اشتباه نکنم ، DynamicResource که به ترتیب اجرا ربط نداشت . اگه اشتباه نکنم ، گفته بودید که StaticResource به ترتیب اجرا وابسته هست (تا ارور نده) .

باز هم اگه اشتباه نکنم ، فکر کنم گفته بودید که در قضیه ی DynamicResource که به پروپرتی های Value یا Property ئه Setter گیر میده که از نوع DependencyObject و پروپرتیِ DependencyProperty نیست ، در واقع گیرش به Value یا Property ئه Setter نیست . بلکه به اون پروپرتی و Resource هایی که به این Value یا Property ئه Setter میخوایم متصل کنیم گیر میدن که چرا اون منابع مون از نوع DependencyObject و پروپرتیِ DependencyProperty نیست . درست میگم؟

تشکر استاد .
 

the_king

مدیرکل انجمن
درباره ی ترتیب اجرا میدونم ولی اگه اشتباه نکنم ، DynamicResource که به ترتیب اجرا ربط نداشت . اگه اشتباه نکنم ، گفته بودید که StaticResource به ترتیب اجرا وابسته هست (تا ارور نده) .
در DynamicResource هم ترتیب اجرا مهم ئه، اما زمان اجراشون متفاوت ئه، در مورد DynamicResource در همون موقع توصیف منبع برای المنت نیازی به در دسترس بودن منبع نیست. اما به این معنی نیست که موقعی که میخواد از منبع استفاده کنه و منبع در دسترس نباشه خطا نده. شما در جایی به منبع فلان اشاره می کنید، چون پویا است و فعلا بهش نیازی نداره لازم نیست موجود باشه، اما قرار بوده قبل از اینکه ازش استفاده بشه اون منبع رو جور کنید، طبق منطق کدتون منبع رو به موقع موجود نکردید و موقعی که میخواد ازش استفاده کنه، هنوز منبع در دسترس نیست. یعنی روالی که منبع رو موجود میکرده و باید به هر طریقی قبلش اجرا میشده هنوز اجرا نشده، در نتیجه خطا میده. حالا چه معرفی منبع پویا باشه و چه نباشه، بالاخره موقعی که لازمه از منبع استفاده بشه باید موجود و در دسترس باشه.

باز هم اگه اشتباه نکنم ، فکر کنم گفته بودید که در قضیه ی DynamicResource که به پروپرتی های Value یا Property ئه Setter گیر میده که از نوع DependencyObject و پروپرتیِ DependencyProperty نیست ، در واقع گیرش به Value یا Property ئه Setter نیست . بلکه به اون پروپرتی و Resource هایی که به این Value یا Property ئه Setter میخوایم متصل کنیم گیر میدن که چرا اون منابع مون از نوع DependencyObject و پروپرتیِ DependencyProperty نیست . درست میگم؟
بله.

در BaseResource.xaml یک استایل عمومی داریم و checkboxTickPath هم شامل میشه :
XML:
    <Style x:Key="MainStyle">
        <Style.Resources>

            <Path x:Key="checkboxTickPath"  Data="M1,7 Q3,7 5,9 Q8,4 12,2 M1,7 Q3.2,7.2 5,11 Q8.2,4.2 12,2"/>

            <!--#region   تمپلیت برای ComboBoxItem -->

            <!--#endregion-->

            <!--#region   تمپلیت برای ComboBox -->

            <!--#endregion-->
اون StaticResource هایی که به checkboxTickPath یا ComboBoxTemplate یا ComboBoxItemTemplate ... اشاره می کنند ایستا هستند و ایستا هم می مانند، دلیلی نداره که DynamicResource باشند. فقط ترتیب توصیف و ارجاع رو رعایت کنید، مثل نمونه Style پیشفرض در سایت مایکروسافت، مثلا منبع ایستای ComboBoxTemplate رو قبل از اینکه در جایی با StaticResource بهش ارجاع کنید توصیف کنید، نه بعدش. قرار بود طبق روال Style های مایکروسافت پیش برید، ببینید با توصیف چی شروع کرد. Template ها رو کجا توصیف کرد؟ قبل از ارجاع یا بعدش؟

در StyleResource.xaml هم Style های اختصاصی رو مشخص می کنیم که از استایل عمومی استفاده می کنند :
منابعی که به Style وابسته هستند رو هم که در خود Style توصیف می کنید و ارجاع ها به این منابع در BaseResource.xaml با DynamicResource ئه، چون موقع توصیف BaseResource.xaml موجود نیستند.

XML:
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="BaseResource.xaml"/>
    </ResourceDictionary.MergedDictionaries>

    <Style x:Key="DarkStyle" BasedOn="{StaticResource MainStyle}">
        <Style.Resources>

            <!--#region   Dark Brushes -->

            <SolidColorBrush x:Key="TextBoxOfComboBoxBackground" Color="#FF646464" />

            <SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE"/>

            .
            .
            .

            <!--#endregion-->
        </Style.Resources>
    </Style>
    
    <Style x:Key="LightStyle" BasedOn="{StaticResource MainStyle}">
        <Style.Resources>

            <!--#region   Light Brushes -->

            <SolidColorBrush x:Key="TextBoxOfComboBoxBackground" Color="#FFEEEEEE" />

            <SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE"/>

            .
            .
            .

            <!--#endregion-->
        </Style.Resources>
    </Style>

هر چند تا Style دیگه هم در StyleResource.xaml اضافه کنید روال همینه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
در DynamicResource هم ترتیب اجرا مهم ئه، اما زمان اجراشون متفاوت ئه، در مورد DynamicResource در همون موقع توصیف منبع برای المنت نیازی به در دسترس بودن منبع نیست. اما به این معنی نیست که موقعی که میخواد از منبع استفاده کنه و منبع در دسترس نباشه خطا نده. شما در جایی به منبع فلان اشاره می کنید، چون پویا است و فعلا بهش نیازی نداره لازم نیست موجود باشه، اما قرار بوده قبل از اینکه ازش استفاده بشه اون منبع رو جور کنید، طبق منطق کدتون منبع رو به موقع موجود نکردید و موقعی که میخواد ازش استفاده کنه، هنوز منبع در دسترس نیست. یعنی روالی که منبع رو موجود میکرده و باید به هر طریقی قبلش اجرا میشده هنوز اجرا نشده، در نتیجه خطا میده. حالا چه معرفی منبع پویا باشه و چه نباشه، بالاخره موقعی که لازمه از منبع استفاده بشه باید موجود و در دسترس باشه.


بله.

در BaseResource.xaml یک استایل عمومی داریم و checkboxTickPath هم شامل میشه :
XML:
    <Style x:Key="MainStyle">
        <Style.Resources>

            <Path x:Key="checkboxTickPath"  Data="M1,7 Q3,7 5,9 Q8,4 12,2 M1,7 Q3.2,7.2 5,11 Q8.2,4.2 12,2"/>

            <!--#region   تمپلیت برای ComboBoxItem -->

            <!--#endregion-->

            <!--#region   تمپلیت برای ComboBox -->

            <!--#endregion-->
اون StaticResource هایی که به checkboxTickPath یا ComboBoxTemplate یا ComboBoxItemTemplate ... اشاره می کنند ایستا هستند و ایستا هم می مانند، دلیلی نداره که DynamicResource باشند. فقط ترتیب توصیف و ارجاع رو رعایت کنید، مثل نمونه Style پیشفرض در سایت مایکروسافت، مثلا منبع ایستای ComboBoxTemplate رو قبل از اینکه در جایی با StaticResource بهش ارجاع کنید توصیف کنید، نه بعدش. قرار بود طبق روال Style های مایکروسافت پیش برید، ببینید با توصیف چی شروع کرد. Template ها رو کجا توصیف کرد؟ قبل از ارجاع یا بعدش؟

در StyleResource.xaml هم Style های اختصاصی رو مشخص می کنیم که از استایل عمومی استفاده می کنند :
منابعی که به Style وابسته هستند رو هم که در خود Style توصیف می کنید و ارجاع ها به این منابع در BaseResource.xaml با DynamicResource ئه، چون موقع توصیف BaseResource.xaml موجود نیستند.

XML:
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="BaseResource.xaml"/>
    </ResourceDictionary.MergedDictionaries>

    <Style x:Key="DarkStyle" BasedOn="{StaticResource MainStyle}">
        <Style.Resources>

            <!--#region   Dark Brushes -->

            <SolidColorBrush x:Key="TextBoxOfComboBoxBackground" Color="#FF646464" />

            <SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE"/>

            .
            .
            .

            <!--#endregion-->
        </Style.Resources>
    </Style>
  
    <Style x:Key="LightStyle" BasedOn="{StaticResource MainStyle}">
        <Style.Resources>

            <!--#region   Light Brushes -->

            <SolidColorBrush x:Key="TextBoxOfComboBoxBackground" Color="#FFEEEEEE" />

            <SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE"/>

            .
            .
            .

            <!--#endregion-->
        </Style.Resources>
    </Style>

هر چند تا Style دیگه هم در StyleResource.xaml اضافه کنید روال همینه.

خیلی ممنون استاد از راهنمایی کامل تون . :rose:
پس کلا منظورتون اینه که Template ها را در یک فایل xaml تعریف کنم (که زودتر از همه لود بشن) و Style ها و Brush ها را در یه فایل دیگه ی xaml (اون Brush ها از Style ها زودتر لود شن) .

بعد اینکه هر جایی در Template ها که در پروپرتی هاشون از StaticResource استفاده شده اما پروپرتی هاشون از نوع DependencyProperty نیستن یا همچنین کلاس هایی که اون پروپرتی ها در اونها قرار دارن ، از نوع DependencyObject نیستن ، این نوع Template ها را بصورت مستقیم در بخش Style ها بیارم (در بخش Template ها نذارم) چون نمیشه در این ها ، بجای StaticResource از DynamicResource ها استفاده کرد .

درسته؟
الان روال کلی تون همینه که در بالا گفتم . درسته؟
تشکر استاد .
 
آخرین ویرایش:

the_king

مدیرکل انجمن
خیلی ممنون استاد از راهنمایی کامل تون . :rose:
پس کلا منظورتون اینه که Template ها را در یک فایل xaml تعریف کنم (که زودتر از همه لود بشن) و Style ها و Brush ها را در یه فایل دیگه ی xaml (اون Brush ها از Style ها زودتر لود شن) .
اگر ترتیب توصیف رو رعایت می کردید که نکردید نیازی به اینکار نبود، اما اینطوری نظم بهتری داره. در ضمن حتی با فایل XAML مجزا هم اگر فراخوانی فایل اش رو بعد ارجاع انجام بدهید همین مشکل میتونه پیش بیاد. مهم رعایت ترتیب ئه.

بعد اینکه هر جایی در Template ها که در پروپرتی هاشون از StaticResource استفاده شده اما پروپرتی هاشون از نوع DependencyProperty نیستن یا همچنین کلاس هایی که اون پروپرتی ها در اونها قرار دارن ، از نوع DependencyObject نیستن ، این نوع Template ها را بصورت مستقیم در بخش Style ها بیارم (در بخش Template ها نذارم) چون نمیشه در این ها ، بجای StaticResource از DynamicResource ها استفاده کرد .
یک مثال بزنید تا بفهمم منظورتون چیه. منطق استفاده از StaticResource و DynamicResource به میشه یا نمیشه نیست، آچار تخت نیست که بخواهید ببینید کدوم بهش میخوره، یک آچار رو امتحان کنیم و اگه اندازه اش درست نبود یک آچار دیگه رو امتحان کنیم. نه. منطق استفاده به این وابسته است که منبع مورد نظر ایستا یا پویا است، منبع قبل ارجاع میتونه موجود باشه یا نه، منبع بعدا ممکنه تغییر کنه یا نه.
ممکنه منبع مورد نظر ایستا باشه و لازم باشه با StaticResource مشخص اش کنید، ولی چون درست کد رو ننوشته باشید خطا بده، این که کد رو درست ننوشته باشید دلیل بر این نمیشه که پس از DynamicResource استفاده کنیم تا خطا نده، باید ایراد کد رو برطرف کنید.

الان روال کلی تون همینه که در بالا گفتم . درسته؟
نه. باید بر اساس ایستا یا پویا بودن منابع انتخاب کنید نه اینکه با این کد کدوم میشه یا نمیشه.
 

SajjadKhati

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


یک مثال بزنید تا بفهمم منظورتون چیه. منطق استفاده از StaticResource و DynamicResource به میشه یا نمیشه نیست، آچار تخت نیست که بخواهید ببینید کدوم بهش میخوره، یک آچار رو امتحان کنیم و اگه اندازه اش درست نبود یک آچار دیگه رو امتحان کنیم. نه. منطق استفاده به این وابسته است که منبع مورد نظر ایستا یا پویا است، منبع قبل ارجاع میتونه موجود باشه یا نه، منبع بعدا ممکنه تغییر کنه یا نه.
ممکنه منبع مورد نظر ایستا باشه و لازم باشه با StaticResource مشخص اش کنید، ولی چون درست کد رو ننوشته باشید خطا بده، این که کد رو درست ننوشته باشید دلیل بر این نمیشه که پس از DynamicResource استفاده کنیم تا خطا نده، باید ایراد کد رو برطرف کنید.


نه. باید بر اساس ایستا یا پویا بودن منابع انتخاب کنید نه اینکه با این کد کدوم میشه یا نمیشه.

خیلی ممنون استاد . :rose:
متوجه شدم .
پروژه ی استایل (Theme) و تمپلیت تمام شد . براتون پیوست میکنم ، اگه نکته ای درباره اش دارین ، ممنون میشم بگین .
اون کمبوباکس ای که در بالای بالای صفحه هست را بزنین ، theme ها را میتونین انتخاب کنین .

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

بعد اینکه استاد ، میخوام قسمت بالا ی ویندوز اصلی (بخش Caption که دکمه های close و minimize و ... قرار دارن) را بردارم . با این کار ، قابلیت تغییر اندازه ی پنجره ی اصلی از کاربر نهایی سلب میشه . اگه در این حالت بخوام قابلیت تغییر اندازه ی پنجره ی اصلی را فعال کنم ، مثل winform که از متد WndProc استفاده میکردیم :

C#:
protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_NCHITTEST)
            {
                Point posScreen = new Point(m.LParam.ToInt32());
                Point posClient = this.PointToClient(posScreen);

                if (posClient.X >= this.ClientSize.Width - BorderWidth && posClient.Y >= this.ClientSize.Height - BorderWidth)
                {
                    m.Result = (IntPtr)17;
                    return;
                }
            }

            base.WndProc(ref m);
        }

در wpf هم باید از این متد استفاده کنیم یا راه دیگه ای هم هست؟
چون یه جا خونده بودم که متد WndProc چون بصورت بازگشتی هست ، سبب کاهش کارایی میشه و واسه ی همین این متد بصورت پیش فرض در wpf مثل winform در دسترس نیست .
کلا از طریق تمپلیت و اینها میشه این قضیه را پیش برد یا باید از متد WndProc استفاده بشه؟
خیلی متشکرم استاد از بابت راهنمایی هاتون :rose:
 

پیوست ها

  • AmozeshWPF_VideoClip.rar
    2.2 مگایابت · بازدیدها: 0
آخرین ویرایش:

the_king

مدیرکل انجمن
بعد اینکه استاد ، میخوام قسمت بالا ی ویندوز اصلی (بخش Caption که دکمه های close و minimize و ... قرار دارن) را بردارم . با این کار ، قابلیت تغییر اندازه ی پنجره ی اصلی از کاربر نهایی سلب میشه . اگه در این حالت بخوام قابلیت تغییر اندازه ی پنجره ی اصلی را فعال کنم ، مثل winform که از متد WndProc استفاده میکردیم :

C#:
protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_NCHITTEST)
            {
                Point posScreen = new Point(m.LParam.ToInt32());
                Point posClient = this.PointToClient(posScreen);

                if (posClient.X >= this.ClientSize.Width - BorderWidth && posClient.Y >= this.ClientSize.Height - BorderWidth)
                {
                    m.Result = (IntPtr)17;
                    return;
                }
            }

            base.WndProc(ref m);
        }

در wpf هم باید از این متد استفاده کنیم یا راه دیگه ای هم هست؟
اینکه چه راه هایی هست رو باید جستجو کنید، من که گوگل نیستم.
معمولا WindowStyle پنجره رو None می کنند تا از کادر پیشفرض خلاص شوند و بعد با المنت های اختصاصی ظاهر پنجره رو بسازند و در هر المنتی که ساخته اید از DragMove برای جابجایی استفاده میشه.


چون یه جا خونده بودم که متد WndProc چون بصورت بازگشتی هست ، سبب کاهش کارایی میشه و واسه ی همین این متد بصورت پیش فرض در wpf مثل winform در دسترس نیست .

کلا از طریق تمپلیت و اینها میشه این قضیه را پیش برد یا باید از متد WndProc استفاده بشه؟
اینکه از WndProc و مدیریت پیام های پنجره تا حد امکان اجتناب کنید ایده خوبیه، هر چقدر از دستکاری روال های سطح پایین فاصله بگیرید احتمال خرابکاری یا ناسازگاری کمتر میشه. ولی نه به این دلایل که اولین باره میشنوم. هر لحظه صد ها پیام بین پنجره برنامه شما و سایر پنجره ها رد و بدل میشه، اساس و مبنای ویندوز بر پایه همین WndProc هست و حذف شدنی نیست. اگر منظور متد بازگشتی است، نه، WndProc متد بازگشتی نیست، متد بازگشتی در کدش خودش رو فراخوانی می کنه، WndProc همچین کاری نمی کنه. و اینکه روال WndProc رو تغییر ندهید و چیزی بهش اضافه نکنید به این معنا نیست که دیگه WndProc ای در کار نباشه.
در گوگل WPF Custom Title Bar رو جستجو کنید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
اینکه چه راه هایی هست رو باید جستجو کنید، من که گوگل نیستم.
معمولا WindowStyle پنجره رو None می کنند تا از کادر پیشفرض خلاص شوند و بعد با المنت های اختصاصی ظاهر پنجره رو بسازند و در هر المنتی که ساخته اید از DragMove برای جابجایی استفاده میشه.



اینکه از WndProc و مدیریت پیام های پنجره تا حد امکان اجتناب کنید ایده خوبیه، هر چقدر از دستکاری روال های سطح پایین فاصله بگیرید احتمال خرابکاری یا ناسازگاری کمتر میشه. ولی نه به این دلایل که اولین باره میشنوم. هر لحظه صد ها پیام بین پنجره برنامه شما و سایر پنجره ها رد و بدل میشه، اساس و مبنای ویندوز بر پایه همین WndProc هست و حذف شدنی نیست. اگر منظور متد بازگشتی است، نه، WndProc متد بازگشتی نیست، متد بازگشتی در کدش خودش رو فراخوانی می کنه، WndProc همچین کاری نمی کنه. و اینکه روال WndProc رو تغییر ندهید و چیزی بهش اضافه نکنید به این معنا نیست که دیگه WndProc ای در کار نباشه.
در گوگل WPF Custom Title Bar رو جستجو کنید.

خیلی ممنون استاد :rose:
من WindowStyle رو روی None و ResizeMode رو روی CanResizeWithGrip ست کردم که مشکلم تا حدودی رفع شد (و در این حالت ، پنجره ی اصلی قابلیت Resize کردن داشت) اما مشکلش در این حالت این بود که در قسمت بالای پنجره ی اصلی ، یه Border ای با ارتفاع حدود 5 پیکسل وجود داشت که من نمیخواستم فقط این Border وجود داشته باشه .

بعد AllowTransparent را True کردم و اون Border هه ، حذف شد و الان درست همون چیزی شد که میخواستم (یعنی بدون TitleBar ، قابلیت تغییر اندازه ی پنجره ی اصلی رو داره) .

اما در لینک زیر میگه که اگه AllowTransparent را True کنید ، ویندوز ، کنترل استایل های قدیمی (حالا توی مثالش ، web browser را مثال زد اما من متوجه نشدم) را نمایش نمیده و همچنین ویندوز ، snap to screen نمیکنه (منظورش اینه که بعضی از ویندوز ها که با نزدیک کردن به پنجره های دیگه ، قابلیت چسبیدن به اون پنجره ها را پیدا میکنن ، این قابلیت را نخواهد داشت؟) .
کلا درباره ی این دو قضیه (نمایش ندادن کنترل استایل های قدیمی) و همچنین snap to screen نشدن ، یه کم توضیح میدین که دقیقا با True کردن AllowTransparent ،چه قابلیت هایی ازش سلب میشه؟



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

تشکر استاد .
 

the_king

مدیرکل انجمن
خیلی ممنون استاد :rose:
من WindowStyle رو روی None و ResizeMode رو روی CanResizeWithGrip ست کردم که مشکلم تا حدودی رفع شد (و در این حالت ، پنجره ی اصلی قابلیت Resize کردن داشت) اما مشکلش در این حالت این بود که در قسمت بالای پنجره ی اصلی ، یه Border ای با ارتفاع حدود 5 پیکسل وجود داشت که من نمیخواستم فقط این Border وجود داشته باشه .

بعد AllowTransparent را True کردم و اون Border هه ، حذف شد و الان درست همون چیزی شد که میخواستم (یعنی بدون TitleBar ، قابلیت تغییر اندازه ی پنجره ی اصلی رو داره) .

اما در لینک زیر میگه که اگه AllowTransparent را True کنید ، ویندوز ، کنترل استایل های قدیمی (حالا توی مثالش ، web browser را مثال زد اما من متوجه نشدم) را نمایش نمیده و همچنین ویندوز ، snap to screen نمیکنه (منظورش اینه که بعضی از ویندوز ها که با نزدیک کردن به پنجره های دیگه ، قابلیت چسبیدن به اون پنجره ها را پیدا میکنن ، این قابلیت را نخواهد داشت؟) .
کلا درباره ی این دو قضیه (نمایش ندادن کنترل استایل های قدیمی) و همچنین snap to screen نشدن ، یه کم توضیح میدین که دقیقا با True کردن AllowTransparent ،چه قابلیت هایی ازش سلب میشه؟

منظورش از snap to screen اینه که پنجره web browser روی صفحه نمیشینه. با فعال کردن AllowTransparent سازگاری پنجره رو کاهش می دهید، میتونه برای انواع کمپوننت ها و یا قابلیت های پنجره مشکل ایجاد کنه. برای همین بجای فعال کردن AllowTransparent برای تغییر ابعاد پنجره از طریق گوشه ها یا یک Thumb کد نویسی می کنند. در گوگل WPF AllowTransparency compatibility رو جستجو کنید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
منظورش از snap to screen اینه که پنجره web browser روی صفحه نمیشینه. با فعال کردن AllowTransparent سازگاری پنجره رو کاهش می دهید، میتونه برای انواع کمپوننت ها و یا قابلیت های پنجره مشکل ایجاد کنه. برای همین بجای فعال کردن AllowTransparent برای تغییر ابعاد پنجره از طریق گوشه ها یا یک Thumb کد نویسی می کنند. در گوگل WPF AllowTransparency compatibility رو جستجو کنید.

سلام
خیلی ممنون استاد .
الان شما میگین از این Allow Transparent استفاده نکنم؟
استایل ها و تمپلیت هایی که در پروژه ی 447 دادم را در این حالت امتحان کردم ، همه شون درست بودن و مشکلی نداشتن (حالا نمیدونم برای بقیه ی کنترل ها و کمپوننت ها مشکل ایجاد میکنه یا نه . البته من از کنترل web browser نمیخوام استفاده کنم .
توی توضیحات پروپرتیِ Window.AllowsTransparency در سایتش نوشته که وجود این پروپرتی برای تسهیل ساخت ویندوزهای بدون rectangular هست . یعنی احتمالا طراحی شده برای این کارها دیگه . نه؟

الان پیشنهادتون ، استفاده از این روش نیست؟
اگه نیست ، روش جایگزین اش را میگید؟
پیشنهادتون ، استفاده از متد WndProc هست یا چیزدیگه؟
یا پیشنهادتون همون قضیه ی Thumb هست؟ اگه اینه ، یه کم توضیح بیشتر یا لینکی میدین که راهکار کلی اش چیه؟

تشکر استاد .
 
آخرین ویرایش:

the_king

مدیرکل انجمن
سلام
خیلی ممنون استاد .
الان شما میگین از این Allow Transparent استفاده نکنم؟
نمیتونم همینطوری پیشنهادی بکنم. معیار انتخاب باید کاربرد باشه، نه نظر من یا فرد دیگری. مثلا در این مورد اگر قرار باشه Style مورد نظر برای پنجره ای بکار بره که داخلش کنترل های خارج محیط WPF استفاده میشه که احتمال ناسازگاری هست، باید از Transparent بودن پنجره اجتناب کنید.

استایل ها و تمپلیت هایی که در پروژه ی 447 دادم را در این حالت امتحان کردم ، همه شون درست بودن و مشکلی نداشتن (حالا نمیدونم برای بقیه ی کنترل ها و کمپوننت ها مشکل ایجاد میکنه یا نه . البته من از کنترل web browser نمیخوام استفاده کنم.
میگید من از کنترل web browser نمیخوام استفاده کنم، اما استفاده کننده Style فقط شما هستید؟ اگر فقط خودتون هستید که هیچ، هیچ ایرادی نمیشه گرفت. بر اساس نیاز خودتون انتخاب کرده اید. اما اگر استفاده کننده اش اشخاص دیگری هستند، جستجو کردید تا ببینید AllowTransparent در چه مواردی ناسازگاری داره؟

توی توضیحات پروپرتیِ Window.AllowsTransparency در سایتش نوشته که وجود این پروپرتی برای تسهیل ساخت ویندوزهای بدون rectangular هست . یعنی احتمالا طراحی شده برای این کارها دیگه . نه؟
بدون rectangular نه، غیر rectangular، یعنی غیر مستطیلی، یعنی هر شکلی بجز مربع و مستطیل.
کادر پنجره شما مستطیل ئه؟ شفاف نیست؟ اگر یک پنجره مستطیل با شفافیت یکنواخت ئه، تناسبی با AllowsTransparency نداره، یا باید شکل مستطیلی نداشته باشه، یا حداقل بخشی اش شفاف، بخشی اش نیمه شفاف باشه. اونوقت قضیه فرق میکرد. اگر پنجره شفاف و غیر مستطیلی نباشه AllowsTransparency برای چی True باشه؟

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

SajjadKhati

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


میگید من از کنترل web browser نمیخوام استفاده کنم، اما استفاده کننده Style فقط شما هستید؟ اگر فقط خودتون هستید که هیچ، هیچ ایرادی نمیشه گرفت. بر اساس نیاز خودتون انتخاب کرده اید. اما اگر استفاده کننده اش اشخاص دیگری هستند، جستجو کردید تا ببینید AllowTransparent در چه مواردی ناسازگاری داره؟


بدون rectangular نه، غیر rectangular، یعنی غیر مستطیلی، یعنی هر شکلی بجز مربع و مستطیل.
کادر پنجره شما مستطیل ئه؟ شفاف نیست؟ اگر یک پنجره مستطیل با شفافیت یکنواخت ئه، تناسبی با AllowsTransparency نداره، یا باید شکل مستطیلی نداشته باشه، یا حداقل بخشی اش شفاف، بخشی اش نیمه شفاف باشه. اونوقت قضیه فرق میکرد. اگر پنجره شفاف و غیر مستطیلی نباشه AllowsTransparency برای چی True باشه؟


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

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

توی همون لینک مشکل Allow Transparent را گفت . ولی مقاله ای که مخصوصا و بصورت یکپارچه مشکلاتش را توضیح بده ، نه (در حد سئوال و جواب مثل همون لینک پیدا کردم) .
از کنترل خارجی استفاده نمیخوام کنم . همش کنترل های خود WPF هست (به دیگران هم کاری ندارم . ربطی به قضیه ی پروژه ی چند پست قبل که درباره ی استایل بودن ، نداره . این قضیه رو برای پروژه ی بکاپ گیری خودم میخوام . قرار نیست پروژه اش را به کسی بدم تا استفاده کنه (منظورم ، محصولش نیست)) .
علاوه بر کنترل های wpf که استفاده میکنم ، کنترل هایی مثل همین ToolKit هم هست که از کلاس های پایه ی wpf ارث بری کردن . از web browser هم قرار نیست استفاده کنم . بخاطر ساخت تمپلیت ، بسیار بسیار بعید میبینم که از کمپوننت های شرکت های دیگه (بجز کمپوننت ToolKit که در جریانید) در wpf استفاده کنم .
اون تمپلیت ها که کنترل DoubleUpDown را هم شامل میشد را تست کردم و مشکلی نداشتن .

نمیدونم با این قضایایی که گفتم ، مشکلی پیش میاد یا نه . اگه مشکل خاصی پیش نیاد ، شخصا دوست دارم از همین روش (True کردن AllowTransparency) استفاده کنم .
-----------------------------
بعد اینکه درباره ی انیمیشن در wpf و فریم دهی کم اش در سیستم ام که میگفتم ، معمولا زمانی این فریم کم اتفاق میافته که از ویژال استودیو برنامه را اجرا کنم . اگه بدون ویژال استودیو و مستقل برنامه را اجرا کنم ، فریم دهی اش خیلی بهتر و در حد عادی میشه .

تشکر استاد .
 

SajjadKhati

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

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

the_king

مدیرکل انجمن
استاد ، در اون انجمن پیام دادم ، ببینم کسی با این حالت (True کردن AllowsTransparency) تجربه ی مشکلی داشته و براش مشکل خاصی بوجود اومده یا نه (تا ببینم میشه روی این روش حساب باز کرد) .
تجربه هر کسی میتونه مفید باشه، اما اگر میخواهید بر اساس پاسخ ها تصمیم بگیرید بهتره به منابعی که فعالیت زیادی دارند رجوع کنید، مثلا AllowsTransparency رو در stackoverflow.com جستجو کنید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
در XML یعنی درج یک تگ Button که داخلش محتوایی با مقدار matn باشه. همین. عینا مشابه تگ Reza ای داخلش محتوایی با مقدار Student باشه. در XML هیچ چیزی بیشتر از این معنی نمیده. تگ Button برای XML همونقدر معنی داره که تگ PEPSI و Maryam.


کاملا به مفسری بستگی داره که داده های دلخواهش رو از داخل کد XML میخونه و تفسیر می کنه. استاندارد XML رعایت شده در این حد که تگی با نام قابل قبول باز شده، محتوای استانداری مابینش قرار گرفته و تگ به درستی بسته شده. اما اینکه با مفسری که قراره داده رو تفسیر کنه چقدر سازگاری داره مربوط به خود XML نیست، مربوط به مفسر ئه. XML فقط داده رو با فرمت استانداردش ثبت کرده ولی در تفسیرش هیچ نقشی نداره.

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


اولا میگه از AllowTransparent استفاده نکنیم.
انگار وقتی که از AllowTransparent استفاده میکنیم ، اگه از کنترل های wpf استفاده کنیم و از کنترل های winform در wpf استفاده نکنیم و همچنین از کنترل web browser هم استفاده نکنیم ، مشکل دیگه ای این AllowTransparent نداره . در چند تا لینک دیدم ، ناسازگاری اش انگار در حد همین هان و اگه از کنترل های خود wpf استفاده بشه ، مشکل خاصی ایجاد نمیشه .
الا ایّ حال ، روش های دیگه رو انتخاب میکنم .

که اگه اشتباه نکنم ، انگار میگه بعد از ست کردن WindowsStyle به None و ResizeMode به NoResize (که هر چند Border ها برداشته میشن اما قابلیت های دیگه مثل تغییر اندازه ی پنجره ، و قابلیت های دیگه هم برداشته میشن) ، در این صورت ، برای برگردوندنِ این قابلیت های از دست رفته (از جمله تغییر اندازه) ، از کلاس WindowChrome استفاده کنید :


اما من هر چی توی سیستم ام میگردم ، فایل اسمبلی Microsoft.Windows.Shell.dll را که لینک بالا در مایکروسافت گفت را پیدا نمیکنم .
لینک زیر در nuget هم میگه نباید از پکیجش استفاده کنیم :


پس چی کار باید کرد؟

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

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

تشکر استاد .
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلامی مجدد

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


و هم لینک زیر :


دو تا کلاس WindowChrome وجود دارن؟
یکی واسه دات نت فریم وورک هه و یکی دیگه واسه ی دات نت کور؟
سئوال پست قبلی هم بی زحمت جواب میدین استاد؟

تشکر
 

the_king

مدیرکل انجمن
اما من هر چی توی سیستم ام میگردم ، فایل اسمبلی Microsoft.Windows.Shell.dll را که لینک بالا در مایکروسافت گفت را پیدا نمیکنم .
لینک زیر در nuget هم میگه نباید از پکیجش استفاده کنیم :


پس چی کار باید کرد؟
در PresentationFramework که از همون ابتدا در پروژه WPF رفرنس داره System.Windows.Shell.WindowChrome هست، البته از نسخه NET 4.5. به بعد. لازم نیست به چیزی رفرنس بدهید.

سلامی مجدد

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


و هم لینک زیر :


دو تا کلاس WindowChrome وجود دارن؟

یکی واسه دات نت فریم وورک هه و یکی دیگه واسه ی دات نت کور؟
یعنی چی دو تا کلاس وجود داره؟
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
در PresentationFramework که از همون ابتدا در پروژه WPF رفرنس داره System.Windows.Shell.WindowChrome هست، البته از نسخه NET 4.5. به بعد. لازم نیست به چیزی رفرنس بدهید.

سلامی مجدد
خیلی ممنون استاد . :rose:
استاد پیدا کردم .
همونطور که گفتید ، از System.Windows.Shell.WindowChrome باید استفاده کنیم که در فایل PresentationFramework.dll هست .
یعنی از همون لینک دوم در پست 457 که دادم .

یعنی چی دو تا کلاس وجود داره؟

در پست 457 ، دو تا لینک دادم که نام هر دو کلاس ، WindowChrome هست اما یکی (اون اولین لینک) در فضای نام Microsoft.Windows.Shell که در فایل Microsoft.Windows.Shell.dll هست) و یکی دیگه در فضای نام System.Windows.Shell که در فایل PresentationFramework.dll هست .
انگار باید از اون دومی (که در فایل PresentationFramework.dll هست) استفاده کنیم . نمیدونم اول اولی برای چیه پس و چرا وجود داره! .

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

اینو برای خودم برای آینده میگم :

کلا برای اینکه وقتی که میخوایم نوار عنوان (title bar) را سفارشی کنیم و در این صورت ، عملکردها و قابلیت های ویندوز استاندارد (مثل تغییر اندازه ی ویندوز ، دکمه های caption ، مینیمایز و ماکزیمایز و ...) را داشته باشیم ، در wpf ، روش استانداردش اینه که از کلاس System.Windows.Shell.WindowChrome (در فایل PresentationFramework.dll) استفاده کنیم .

روش استفاده از این کلاسِ WindowChrome ، بصورت کلی اینه که اول ، پروپرتیِ WindowStyle مربوط به Window (ای که میخوایم شیِ WindowChrome را براش بکار ببریم) را روی None تنظیم کنیم .

بعد ، Attached Property ئه WindowChrome (در کلاسِ WindowChrome) را برای Window اصلی مون ، مقداردهی میکنیم (که این پروپرتیِ WindowChrome ، شی ای از نوع WindowChrome میخواد) .

مثال :

XML:
<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"
        x:Class="WPF_Practice.TemplateWindow"
        mc:Ignorable="d"
        Title="TemplateWindow" Height="900" Width="1600" WindowStyle="None">

    <WindowChrome.WindowChrome>
        <WindowChrome CaptionHeight="0" ResizeBorderThickness="5"/>
    </WindowChrome.WindowChrome>


    <Grid x:Name="mainGrid" Background="#FF2D2D2D">
   
    </Grid>

</Window>

پروپرتیِ CaptionHeight ، ارتفاع نوار ابزار (ای که دیده نمیشه) برای قابلیت جابجایی و ... را از قسمت بالای client size ئه ویندوز مون مشخص میکنه . در واقع میشه گفت که همون اندازه ی title bar ای که دیده نمیشه اما عملکرد همون title bar را داره (مثل جابجایی و ...) را فراهم میکنه .
مشخص هست هر عددی بجز صفر باشه ، اگه کنترلی از درون برنامه مون ، در حیطه و درون این محدوده (در قسمت بالای برنامه مون) قرار بگیره ، hit testing اون کنترل مون ، عمل نمیکنه .

ResizeBorderThickness هم ضخامت دور ویندوز اصلی برنامه مون که دیده نمیشه را مشخص میکنه که وقتی موس را روی اون محوطه میبریم ، میتونیم با کلیک و درگ ، ویندوز مون را تغییر اندازه بدیم .

نکته اینکه : اگه پروپرتیِ WindowStyle مربوط به ویندوزمون را روی None قرار ندیم و همچنین پروپرتیِ WindowChrome.WindowChrome را هم به ویندوزمون اِعمال کنیم ، ممکنه مشکل hit testing بوجود بیاد (نمیدونم چرا) و این مشکل انگار با تنظیم پروپرتیِ GlassFrameThickness ئه WindowChrome به مقدار 0 ، احتمالا حل میشه .

تشکر استاد :rose:
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلامی مجدد
استاد ، چرا وقتی کنترل های winform را توسط کنترل WindowsFormsHost ، وارد wpf میکنیم ، نمای گرافیکیِ کنترل هایی که درون WindowsFormsHost هستن ، از دست میره؟

نمای گرافیکی شون انگار شبیه کنترل ها در ویندوز 98 میشه (البته من خودم ویندوز 98 نداشتم ولی قبلا عکس هاشو دیدم) .
پروپرتیِ AllowTransparent ئه ویندوز اصلی هم False هست .
کاری نمیشه کرد که با همون گرافیکی که در WindowsForm نمایش داده میشدن ، در wpf (در کنترل WindowsFormsHost) هم همون جوری نمایش داده بشن؟

تشکر استاد .
 

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

بالا