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

the_king

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

در پست 457 ، دو تا لینک دادم که نام هر دو کلاس ، WindowChrome هست اما یکی (اون اولین لینک) در فضای نام Microsoft.Windows.Shell که در فایل Microsoft.Windows.Shell.dll هست) و یکی دیگه در فضای نام System.Windows.Shell که در فایل PresentationFramework.dll هست .
انگار باید از اون دومی (که در فایل PresentationFramework.dll هست) استفاده کنیم . نمیدونم اول اولی برای چیه پس و چرا وجود داره! .
اگه دقت کنید مستندات مایکروسافت نسخه داره که میگه در مورد چه محصولی است، شما دارید مستندات مربوط به یک اسمبلی جانبی NET 4. رو با مستندات NET 4.5 (و NET. Core 3.1) مقایسه می کنید. یک WindowChrome ای در Microsoft.Windows.Shell بوده که یک dll مستقل و جانبی برای استفاده در NET 4. بوده که قابل دانلود بوده.
بعد که مورد توجه قرار گرفته در NET 4.5 تحت فضای نام System.Windows.Shell معرفی شده.

سلامی مجدد
استاد ، چرا وقتی کنترل های winform را توسط کنترل WindowsFormsHost ، وارد wpf میکنیم ، نمای گرافیکیِ کنترل هایی که درون WindowsFormsHost هستن ، از دست میره؟
اعمال Visual Styles یک قابلیت توسعه یافته ویندوز بوده که برای حفظ سازگاری روی برنامه هایی که درخواستش رو ندارند فعال نمیشه تا کنترل ها به همون حالتی دیده بشن که طراح شون مد نظر داشته. برای همین بصورت پیشفرض سیستم عامل Visual Styles رو روی برنامه ها اعمالش نمی کنه. به چند طریق برنامه میتونه در همون ابتدا و قبل از اینکه کنترلی ایجاد بشه به سیستم عامل اعلام کنه که از Visual Styles پشتیبانی می کنه تا سیستم عامل برای اون برنامه فعالش کنه. حتما اون سطر کد Application.EnableVisualStyles رو در Program.cs برنامه های Windows Forms دیده اید. چون بصورت پیشفرض WPF استفاده ای از Visual Styles نمی کنه، همچین درخواستی رو نمی کنه. باید کدی رو اضافه کنید تا برنامه در همون ابتدای کار به سیستم عامل اعلام کنه که Visual Styles رو پشتیبانی می کنه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
اگر چیزی بهتر یا بهینه تر باشه باید جدول مقایسه ای باشه که با ارقام این مساله رو نشون بده.
این پست و نمونه کدش رو ببینید :
wpfvswinforms.rar
سوال: طراحی کامپوننت در WPF و استفاده در Windows Form

سلامی مجدد استاد (خیلی ممنون از جواب پست قبلی تون) .
استاد ، من هنوز متوجه نشدم شما توی این پروژه از کجا میدونستین که متد DrawingContext.DrawText ئه WPF ، از متد Graphics.DrawString ئه WinForm ، خیلی خیلی کندتر عمل میکنه (حدود 10 برابر) . با اونکه wpf هم خیلی بیشتر کارت گرافیک و حتی cpu را درگیر میکنه اما 10 برابر کند تر هه .

از کجا متوجه شدید تفاوت کارایی شون این قدره و اینکه باز در کجاها و در چه توابع گرافیکی ای این قدر تفاوت کارایی شون متفاوت هست و آیا کار یا طرفندی میشه انجام داد که کارایی گرافیکی (فرضا همین رسم DrawingContext.DrawText) در wpf را بهبود بخشید تا به کارایی و سرعت winform برسه؟
تشکر
 

the_king

مدیرکل انجمن
سلامی مجدد استاد (خیلی ممنون از جواب پست قبلی تون) .
استاد ، من هنوز متوجه نشدم شما توی این پروژه از کجا میدونستین که متد DrawingContext.DrawText ئه WPF ، از متد Graphics.DrawString ئه WinForm ، خیلی خیلی کندتر عمل میکنه (حدود 10 برابر) . با اونکه wpf هم خیلی بیشتر کارت گرافیک و حتی cpu را درگیر میکنه اما 10 برابر کند تر هه .

از کجا متوجه شدید تفاوت کارایی شون این قدره و اینکه باز در کجاها و در چه توابع گرافیکی ای این قدر تفاوت کارایی شون متفاوت هست و آیا کار یا طرفندی میشه انجام داد که کارایی گرافیکی (فرضا همین رسم DrawingContext.DrawText) در wpf را بهبود بخشید تا به کارایی و سرعت winform برسه؟
تشکر
زمانی که معماری و نحوه کار یک سیستم رو بدونید نقاط قوت و ضعف اش رو بهتر درک می کنید. در WPF درخواست های رسم شما باید توسط نخ مستقلی رندر بشه که تحت کنترل شما نیست، همونطور که به GC نمی توانید بگید حافظه بلا استفاده این متغیر رو همین الان آزاد کن. زمانی که نخ رندر کننده به درخواست های شما پاسخ آنی نده، نمی توانید رسم هایی با نرخ بالا رو بی درنگ انجام بدهید، حتی اگر قدرت رندر بالایی داشته باشه. در Windows Forms موتور رندر کننده قوی ای وجود نداره اما در عوض پاسخ به درخواست های رسم اون معطلی WPF رو هم نداره. هر معماری ای نقاط قوت و ضعف خودش رو داره، معماری رو نمیشه تغییر داد. برای همین هر پلتفرمی برای یکسری کاربرد ها مناسبه و برای یکسری کاربرد ها مناسب نیست.
 

SajjadKhati

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

خیلی ممنون استاد . :rose:
یعنی بخاطر سوئیچ بین نخ ها (یی که در wpf میخوان عملیات رسم را انجام بدن (در نخ ای که قراره رسم صورت بگیره که فکر کنم نخ اصلی باشه) _ چون بالاخره رسم باید در یک نخ انجام بشه . درسته؟) باعث ایجاد این کندی شدید میشه؟

چون نباید صرفا بخاطر درخواست دادن باشه . چون در winform هم گفتید که درخواست برای رسم وجود داره (و با فراخونی متد Invalidate ، صرفا درخواست رسم ارسال میشه و به این معنی نیست که winform ، همون موقع ، رسم را انجام بده) .

بعد اینکه زمانی که سئوالات کنترل TransparentControl را ازتون میپرسیدم ، در winform ، یه متدی معرفی کرده بودید که این متد را بعد از متد Invalidate فراخونی میکردیم و باعث میشد تا winform ، در سریع ترین زمان ممکن ، این درخواست رسم را اجرایی کنه (الان نام متد را دقیق یادم نیست) . همچنین در قضیه ی garbage collector هم ، متد Collect ، این عمل را انجام میداد .
حالا توی wpf یه همچین متدی نیست که باعث بشه درخواست رسم را در سریع ترین زمان ممکن ، اجرا کنه؟

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

بعد اینکه در نسخه ی 2015 ویژال استودیو ، برای ساخت dll ، گزینه ی class library (فقط با همین نام) بود که حالا بعد از انتخابش ، نسخه ی دات نت فریم وورک مون را انتخاب میکردیم . توی نسخه ی 2019 ، class library به 3 گزینه ی مجزای .net standard و .net framework و .net core تقسیم شدن .
اگه برای برنامه های تحت دسکتاپ بخوام ، همون class library (.net framework) را انتخاب کنم دیگه . درسته؟

و بعد اینکه اگه بخوام dll ای درست کنم که بتونم یه کنترل wpf ای را که کدهای style اش در فایل xaml هست را درست کنم ، لینک زیر راهنمای این کاره؟ :


خروجی اش هم میخوام unmanaged باشه .
تشکر استاد .
 

the_king

مدیرکل انجمن
یعنی بخاطر سوئیچ بین نخ ها (یی که در wpf میخوان عملیات رسم را انجام بدن (در نخ ای که قراره رسم صورت بگیره که فکر کنم نخ اصلی باشه) _ چون بالاخره رسم باید در یک نخ انجام بشه . درسته؟) باعث ایجاد این کندی شدید میشه؟
نه. ربطی به سوئیچ کردن نداره.

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

بعد اینکه زمانی که سئوالات کنترل TransparentControl را ازتون میپرسیدم ، در winform ، یه متدی معرفی کرده بودید که این متد را بعد از متد Invalidate فراخونی میکردیم و باعث میشد تا winform ، در سریع ترین زمان ممکن ، این درخواست رسم را اجرایی کنه (الان نام متد را دقیق یادم نیست) . همچنین در قضیه ی garbage collector هم ، متد Collect ، این عمل را انجام میداد.
حالا توی wpf یه همچین متدی نیست که باعث بشه درخواست رسم را در سریع ترین زمان ممکن ، اجرا کنه؟
خود همین چیزی که میگید میشه یک درخواست از یک نخ مستقل دیگه. چطور که وقتی به GC میگیم لطفا حافظه های بلا استفاده رو آزاد کن فورا اینکار رو نمیکنه. مثل اینه که بگم به فلانی زنگ میزنم گوشی رو بر نمیداره، بگید خوب بهش زنگ بزن بگو فوری گوشی رو بردار. همون شرایط ئه، معماری رندر اش بلادرنگ نیست، درخواست در خود نخ اجرا نمیشه که به محض تموم شدن اجرای کدتون نوبت اجراش برسه. ببینید مایکروسافت در مورد این رندر کردن چی میگه :
The DrawingContext allows you to populate a Visual with visual content. When you use a DrawingContext object's draw commands, you are actually storing a set of render data that will later be used by the graphics system; you are not drawing to the screen in real-time.​
اگر تمایل داشتید در مورد WPF Real-Time Rendering جستجو کنید.

بعد اینکه در نسخه ی 2015 ویژال استودیو ، برای ساخت dll ، گزینه ی class library (فقط با همین نام) بود که حالا بعد از انتخابش ، نسخه ی دات نت فریم وورک مون را انتخاب میکردیم . توی نسخه ی 2019 ، class library به 3 گزینه ی مجزای .net standard و .net framework و .net core تقسیم شدن .
اگه برای برنامه های تحت دسکتاپ بخوام ، همون class library (.net framework) را انتخاب کنم دیگه . درسته؟
بله.

و بعد اینکه اگه بخوام dll ای درست کنم که بتونم یه کنترل wpf ای را که کدهای style اش در فایل xaml هست را درست کنم ، لینک زیر راهنمای این کاره؟ :


خروجی اش هم میخوام unmanaged باشه .
تشکر استاد .
Unmanaged باشه؟ WPF بر اساس محیط Managed طراحی شده، چطوری خروجی کتابخانه ای که از WPF استفاده میکنه Unmanaged باشه؟ همچین ترکیبی ممکن نیست.
 

SajjadKhati

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

بله. صرفا بخاطر درخواست نیست، زمان پاسخگویی به اون درخواست اینجا اهمیتش رو نشون میده.

خیلی ممنون استاد :rose:
یعنی به سوئیچ بین نخ ها ربط نداره . صرفا بخاطر اینه که وقتی که درخواست رسم رو میدیم ، wpf ، پاسخ آنی به رسم مون نمیده و در واقع تاخیر در پاسخ و اجرای درخواست رسم مون در wpf ، خیلی بیشتر از تاخیرِ اجرای درخواست رسم مون در win form هست . درسته؟
وگرنه هر دوی win form و wpf ، درخواست رسم را میدن و خود برنامه نویس ، رسم را انجام نمیده .

خود همین چیزی که میگید میشه یک درخواست از یک نخ مستقل دیگه. چطور که وقتی به GC میگیم لطفا حافظه های بلا استفاده رو آزاد کن فورا اینکار رو نمیکنه. مثل اینه که بگم به فلانی زنگ میزنم گوشی رو بر نمیداره، بگید خوب بهش زنگ بزن بگو فوری گوشی رو بردار. همون شرایط ئه، معماری رندر اش بلادرنگ نیست، درخواست در خود نخ اجرا نمیشه که به محض تموم شدن اجرای کدتون نوبت اجراش برسه. ببینید مایکروسافت در مورد این رندر کردن چی میگه :

اگر تمایل داشتید در مورد WPF Real-Time Rendering جستجو کنید.

بله.

الان اگه اشتباه نکنم ، متد Update ئه Control در win form ، باعث میشه تا در سریعترین زمان ممکن ، بعد از فراخونی متد Invalidate ، رسم صورت بگیره و این تاخیر را به حداقل زمانش کاهش میده . همچنین متد Collect توی GC .
حالا اگه توی wpf بخوایم این کار را کنیم و تاخیر در رسم را به حداقل ترین زمان ممکن برسونیم ، شدنی هست و باید درباره ی WPF Real-Time Rendering تحقیق کنم؟

Unmanaged باشه؟ WPF بر اساس محیط Managed طراحی شده، چطوری خروجی کتابخانه ای که از WPF استفاده میکنه Unmanaged باشه؟ همچین ترکیبی ممکن نیست.

حالا unmanaged اش را چندان کاری ندارم (سئوالم درباره ی unmanaged بودنش نیست) . با کتابخونه ی UnmanagedExports در nuget میشه این کار را انجام داد .

میخوام بدونم اگه کنترل های wpf (ای که Style و Template خاصی در فایل xaml براش نوشته شد) را بخوام در یه dll (ای که Managed هست . با Unmanaged بودن اش کار ندارم) ای بیارم و یه کنترلی در اون dll بسازم که اون style در xaml را براش بکار ببرم ، جوابش توی این لینکی که دادم هست یا جوابش اون نیست؟

تشکر استاد .
 

the_king

مدیرکل انجمن
یعنی به سوئیچ بین نخ ها ربط نداره . صرفا بخاطر اینه که وقتی که درخواست رسم رو میدیم ، wpf ، پاسخ آنی به رسم مون نمیده و در واقع تاخیر در پاسخ و اجرای درخواست رسم مون در wpf ، خیلی بیشتر از تاخیرِ اجرای درخواست رسم مون در win form هست . درسته؟
وگرنه هر دوی win form و wpf ، درخواست رسم را میدن و خود برنامه نویس ، رسم را انجام نمیده .
بله.
الان اگه اشتباه نکنم ، متد Update ئه Control در win form ، باعث میشه تا در سریعترین زمان ممکن ، بعد از فراخونی متد Invalidate ، رسم صورت بگیره و این تاخیر را به حداقل زمانش کاهش میده . همچنین متد Collect توی GC .
بله. از نظر تکنیکی کنترل رو وادار میکنه که ناحیه هایی که قبلا درخواست Invalidate شدنشون دریافت شده رو رسم مجدد کنه. یعنی رسم مجدد کنترل جلو بیافته، همین الان و سریع انجام بشه، معطل رخداد های آینده نشه.

حالا اگه توی wpf بخوایم این کار را کنیم و تاخیر در رسم را به حداقل ترین زمان ممکن برسونیم ، شدنی هست و باید درباره ی WPF Real-Time Rendering تحقیق کنم؟
معماری WPF رو نمی توانید تغییر بدهید، پیشنهاد دادم تحقیق کنید تا مشکلات فنی قضیه رو درک کنید، ببینید که Real-Time Rendering چرا و چطور در WPF محدودیت داره. نه اینکه راه حلی برای تغییر معماری WPF پیدا کنید. وقتی معماری پلتفرمی رو درک کنید بهتر ازش استفاده می کنید.

حالا unmanaged اش را چندان کاری ندارم (سئوالم درباره ی unmanaged بودنش نیست) . با کتابخونه ی UnmanagedExports در nuget میشه این کار را انجام داد .
نه. با UnmanagedExports هم همچین اتفاقی نمی افته، Export کردن یک متد از محیط Managaed به محیط Unmanaged به این معنا نیست که محیط Unmanaged بتونه از اشیاء Managed استفاده کنه. شما صرفا اشیاء ای رو می توانید در محیط Unmanaged استفاده کنید که به نوع داده های Unmanaged تبدیل شده باشه، مثل int و string و ...

میخوام بدونم اگه کنترل های wpf (ای که Style و Template خاصی در فایل xaml براش نوشته شد) را بخوام در یه dll (ای که Managed هست . با Unmanaged بودن اش کار ندارم) ای بیارم و یه کنترلی در اون dll بسازم که اون style در xaml را براش بکار ببرم ، جوابش توی این لینکی که دادم هست یا جوابش اون نیست؟
در Visual Studio 2017 که همچین مشکلی نمی بینم که نیازی به تغییر تنظیمات پروژه باشه، اما اگر نمی توانید یک (User Control (WPF رو به پروژه اضافه کنید ضرری نداره، راه حل اش رو امتحان کنید. البته اگر برای WPF کنترل طراحی می کنید، برای پروژه مورد نظر شما نوع پروژه WPF User Control Library مناسبتر ئه.
 

SajjadKhati

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

در ادامه ی بحثی که در اون تاپیک درباره ی هندل و اینها داشتیم ، اول اینکه درست گفتید و باید اون user control را درون یه window میذاشتم و window را نمایش میدادم تا هندل user control را بتونه بگیره . که بازم انگار هندل user control نیست و هندل window انگار محسوب میشه .


در پروژه ی زیر که در این رابطه هست و پیوست میکنم ، مشکل اینه که هر وقت اون دکمه (ای که روش نوشته "Button") را کلیک میکنیم (که متد استاتیک
UserControl1.CreateComboBox را فراخونی میکنه) ، در متد CreateComboBox ، با اونکه Margin اش را ست کردم و موقع فراخونیِ متد CreateComboBox هم مقدار ثابتی بهش دادم ، اما با هر بار کلیک روی اون دکمه ، هر شیِ کمبوباکس را در یه جایی از صفحه (در مکان های متفاوت) ایجاد میکنه . چرا و برای رفع مشکلش چی کار باید کنم؟

این هم کد متد CreateComboBox (که البته در پروژه هم هست) :

C#:
        [DllExport("CreateComboBox", CallingConvention.StdCall)]
        public static int CreateComboBox(int hwndParent, int x, int y, int width, int height)
        {
            UserControl1 myUserControl = new UserControl1();


            Window window = new Window();
            window.HorizontalAlignment = HorizontalAlignment.Left;
            window.VerticalAlignment = VerticalAlignment.Top;
            window.Margin = new Thickness(x, y, 0, 0);
            window.Width = width;
            window.Height = height;
            window.Content = myUserControl;
            window.Background = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
            window.ResizeMode = ResizeMode.NoResize;
            window.WindowStyle = WindowStyle.None;
            window.Show();

            HwndSource hwndChildSource = HwndSource.FromVisual(myUserControl) as HwndSource;
            if (hwndChildSource == null)
            {
                return -1;
            }
            else
            {
                IntPtr hwndChild = hwndChildSource.Handle;
                if (hwndChild != IntPtr.Zero)
                {
                    BusinessLogic.SetParent(hwndChild, (IntPtr)hwndParent);
                    return hwndChild.ToInt32();
                }
                return -1;
            }

        }

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

پیوست ها

  • WpfControlLibrary_ComboBox.rar
    629.3 کیلوبایت · بازدیدها: 1

the_king

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

در ادامه ی بحثی که در اون تاپیک درباره ی هندل و اینها داشتیم ، اول اینکه درست گفتید و باید اون user control را درون یه window میذاشتم و window را نمایش میدادم تا هندل user control را بتونه بگیره . که بازم انگار هندل user control نیست و هندل window انگار محسوب میشه .


در پروژه ی زیر که در این رابطه هست و پیوست میکنم ، مشکل اینه که هر وقت اون دکمه (ای که روش نوشته "Button") را کلیک میکنیم (که متد استاتیک
UserControl1.CreateComboBox را فراخونی میکنه) ، در متد CreateComboBox ، با اونکه Margin اش را ست کردم و موقع فراخونیِ متد CreateComboBox هم مقدار ثابتی بهش دادم ، اما با هر بار کلیک روی اون دکمه ، هر شیِ کمبوباکس را در یه جایی از صفحه (در مکان های متفاوت) ایجاد میکنه . چرا و برای رفع مشکلش چی کار باید کنم؟

این هم کد متد CreateComboBox (که البته در پروژه هم هست) :

C#:
        [DllExport("CreateComboBox", CallingConvention.StdCall)]
        public static int CreateComboBox(int hwndParent, int x, int y, int width, int height)
        {
            UserControl1 myUserControl = new UserControl1();


            Window window = new Window();
            window.HorizontalAlignment = HorizontalAlignment.Left;
            window.VerticalAlignment = VerticalAlignment.Top;
            window.Margin = new Thickness(x, y, 0, 0);
            window.Width = width;
            window.Height = height;
            window.Content = myUserControl;
            window.Background = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
            window.ResizeMode = ResizeMode.NoResize;
            window.WindowStyle = WindowStyle.None;
            window.Show();

            HwndSource hwndChildSource = HwndSource.FromVisual(myUserControl) as HwndSource;
            if (hwndChildSource == null)
            {
                return -1;
            }
            else
            {
                IntPtr hwndChild = hwndChildSource.Handle;
                if (hwndChild != IntPtr.Zero)
                {
                    BusinessLogic.SetParent(hwndChild, (IntPtr)hwndParent);
                    return hwndChild.ToInt32();
                }
                return -1;
            }

        }

تشکر استاد :rose:
چیکار دارید می کنید؟ برای قرار دادن یک کنترل UserControl1 روی mainGrid چرا Window می سازید؟ Window این وسط نقشش چیه؟ چرا باید یک Window رو داخل Grid بذارید؟ Window همیشه باید ریشه باشه، نه فرزند.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
چیکار دارید می کنید؟ برای قرار دادن یک کنترل UserControl1 روی mainGrid چرا Window می سازید؟ Window این وسط نقشش چیه؟ چرا باید یک Window رو داخل Grid بذارید؟ Window همیشه باید ریشه باشه، نه فرزند.

خیلی ممنون استاد .
ویندوز نقشش اینه که چون این dll را برای اتوپلی میخوام . اون پروژه ای که به عنوان غیر از library ساخته شد ، فقط برای تست و دیباگ گیریِ اون library هست .
حالا اگه ویندوز ، به عنوان ریشه استفاده نشه ، چه اشکالی داره؟

بعد اینکه استاد ، الان وقتی پروژه مون را توی یه نسخه از دات net framework بنویسیم ، زمان اجرای برنامه ، نیاز هست‌که کاربر نهایی ، همون نسخه از دات net framework را نصب کنه تا برنامه اجرا بشه ؛ حالا اگه زمان ساخت پروژه ، از دات net core استفاده کنیم ، دیگه نیازی نیست که کاربر ، موقع استفاده از برنامه ، چیزی را نصب کنه؟
فرضا هم فقط اون برنامه را فقط بخوایم توی ویندوز اجرا کنیم (مثل همین برنامه)

تشکر استاد
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
ویندوز نقشش اینه که چون این dll را برای اتوپلی میخوام . اون پروژه ای که به عنوان غیر از library ساخته شد ، فقط برای تست و دیباگ گیریِ اون library هست .
حالا اگه ویندوز ، به عنوان ریشه استفاده نشه ، چه اشکالی داره؟
Window برای قرار گرفتن در یک المنت دیگه طراحی نشده، فقط باید المنت ریشه باشه :
A Window is a ContentControl, which means that it can contain a single object of any type (such as a string, an image, or a panel). For more information, see the ContentControl class. Also, Window is a root element and, therefore, cannot be part of another element's content.​

بعد اینکه استاد ، الان وقتی پروژه مون را توی یه نسخه از دات net framework بنویسیم ، زمان اجرای برنامه ، نیاز هست‌که کاربر نهایی ، همون نسخه از دات net framework را نصب کنه تا برنامه اجرا بشه ؛ حالا اگه زمان ساخت پروژه ، از دات net core استفاده کنیم ، دیگه نیازی نیست که کاربر ، موقع استفاده از برنامه ، چیزی را نصب کنه؟
هر کدوم ستاپ خودشون رو دارند و بهش هم نیاز هست.
 

SajjadKhati

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

1.JPG

اینها همون TransparentControl هایی هستند که در winform طراحی کردیم (که در جریان هستید) و این قابلیت را دارن که هم تصویر و هم متن و یا هر دو را رسم کنن .

حالا میخوام توی Button ها در wpf ، یه template ای بنویسم که هم اون شکل ها را رسم کنه (به عنوان shap و Path) و هم اگه شامل متن ای بود (مثل دکمه ی "تایید" در عکس بالا) ، اون متن را هم رسم کنه ، دقیقا باید چه راهبرد کلی ای داشته باشم؟ (علاوه بر این ، مثل کنترل های combobox و ... که قبلا style هم براشون نوشتیم ، این button ها هم دارای استایل dark و light هستن) .

یه روش اینه که data ی مربوط به هر رسم ای را که برای اون Button میخوام انجام بده را توی مثلا پروپرتیِ Content اش بریزم و توی Template اش ، از این اطلاعات ، رسمِ Path را انجام بدم .
اما این جوری دیگه نمیشه اطلاعات متن (اگه اون کنترل شامل متن باشه) را از طریق Content در xaml جدا کرد (میشه؟) . بنابراین برای حل اش میشه اطلاعات متن را در یه پروپرتیِ دیگه مثل Tag ریخت و ازش برای رسم در Template استفاده کرد . اما میگم چون اطلاعات در دو پروپرتیِ مجزا وارد میکنیم که بصورت اساسی ممکنه بعدا در کدنویسی سی شارپ برای کارهای دیگه ای استفاده بشه ، این روش اصولی نباشه .

روش دیگه اینکه به نظرم یه کلاس CustomButton بسازم که از Button ها ارث بری کنه و دو تا پروپرتی در اون کلاس برای این کارها در نظر بگیرم که یکی برای رسم Path بکار بره و یکی هم برای رسم متن .

به نظر شما ، چه روشی ، اصولی هه؟
تشکر استاد .
 

the_king

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

مشاهده پیوست 113659

اینها همون TransparentControl هایی هستند که در winform طراحی کردیم (که در جریان هستید) و این قابلیت را دارن که هم تصویر و هم متن و یا هر دو را رسم کنن .

حالا میخوام توی Button ها در wpf ، یه template ای بنویسم که هم اون شکل ها را رسم کنه (به عنوان shap و Path) و هم اگه شامل متن ای بود (مثل دکمه ی "تایید" در عکس بالا) ، اون متن را هم رسم کنه ، دقیقا باید چه راهبرد کلی ای داشته باشم؟ (علاوه بر این ، مثل کنترل های combobox و ... که قبلا style هم براشون نوشتیم ، این button ها هم دارای استایل dark و light هستن) .

یه روش اینه که data ی مربوط به هر رسم ای را که برای اون Button میخوام انجام بده را توی مثلا پروپرتیِ Content اش بریزم و توی Template اش ، از این اطلاعات ، رسمِ Path را انجام بدم .
اما این جوری دیگه نمیشه اطلاعات متن (اگه اون کنترل شامل متن باشه) را از طریق Content در xaml جدا کرد (میشه؟) . بنابراین برای حل اش میشه اطلاعات متن را در یه پروپرتیِ دیگه مثل Tag ریخت و ازش برای رسم در Template استفاده کرد . اما میگم چون اطلاعات در دو پروپرتیِ مجزا وارد میکنیم که بصورت اساسی ممکنه بعدا در کدنویسی سی شارپ برای کارهای دیگه ای استفاده بشه ، این روش اصولی نباشه .

روش دیگه اینکه به نظرم یه کلاس CustomButton بسازم که از Button ها ارث بری کنه و دو تا پروپرتی در اون کلاس برای این کارها در نظر بگیرم که یکی برای رسم Path بکار بره و یکی هم برای رسم متن .

به نظر شما ، چه روشی ، اصولی هه؟
تشکر استاد .
شما با دیدگاه یک کنترل Windows Forms در WPF کنترلی رو طراحی می کنید که از کنترل دکمه پیشفرض WPF محدودیت بیشتری داره، دست طراح در تغییر ظاهر دکمه استاندارد بازتر از کنترل شما میشه. اما در هر صورت می توانید یک مشخصه جدید برای کلاس کنترل تون یا یک مشخصه الحاقی جدید مستقل از کلاس کنترل تون طراحی کنید تا بجز Content مشخصه دیگری رو هم برای آیکونش بکار ببرید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلی ممنون استاد .
استاد ، کلاس دارم بنام ShapeTextButton که از کلاس Button ارث بری میکنه و یه پروپرتی بنام ButtonShape از نوع System.Windows.Shape.Path داره .
اگه براش همچین تمپلیت ای بنویسم ، مشکلی نداره :

XML:
    <ControlTemplate x:Key="ShapeTextButtonTemplate" TargetType="{x:Type CustomControls:ShapeTextButton}">
        <Grid Name="MainGrid" Background="Transparent">
            <Path Name="Shape" Margin="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=ButtonShape.Margin}"  />
        </Grid>
    </ControlTemplate>

یعنی با Binding ، مشکلی نداره اما وقتی بجای Binding ، از TemplateBinding استفاده کنم و کد زیر را بنویسم :

XML:
    <ControlTemplate x:Key="ShapeTextButtonTemplate" TargetType="{x:Type CustomControls:ShapeTextButton}">
        <Grid Name="MainGrid" Background="Transparent">
            <Path Name="Shape" Margin="{TemplateBinding ButtonShape.Margin}"  />
        </Grid>
    </ControlTemplate>

ارور زیر را میده :

کد:
    ButtonShape is not supported in a Windows Presentation Foundation (WPF) project.

چرا؟
تشکر استاد .
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
استاد ، کلاس دارم بنام ShapeTextButton که از کلاس Button ارث بری میکنه و یه پروپرتی بنام ButtonShape از نوع System.Windows.Shape.Path داره .
اگه براش همچین تمپلیت ای بنویسم ، مشکلی نداره :

XML:
    <ControlTemplate x:Key="ShapeTextButtonTemplate" TargetType="{x:Type CustomControls:ShapeTextButton}">
        <Grid Name="MainGrid" Background="Transparent">
            <Path Name="Shape" Margin="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=ButtonShape.Margin}"  />
        </Grid>
    </ControlTemplate>

یعنی با Binding ، مشکلی نداره اما وقتی بجای Binding ، از TemplateBinding استفاده کنم و کد زیر را بنویسم :

XML:
    <ControlTemplate x:Key="ShapeTextButtonTemplate" TargetType="{x:Type CustomControls:ShapeTextButton}">
        <Grid Name="MainGrid" Background="Transparent">
            <Path Name="Shape" Margin="{TemplateBinding ButtonShape.Margin}"  />
        </Grid>
    </ControlTemplate>

ارور زیر را میده :

کد:
    ButtonShape is not supported in a Windows Presentation Foundation (WPF) project.

چرا؟
تشکر استاد .
لابد فقط مشخصه تعریف کرده اید، DependencyProperty ای که XAML بخواد استفاده کنه نداره. یک ButtonShapeProperty ای نیست که TemplateBinding لازم داره.

 

SajjadKhati

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


خیلی ممنون استاد .
اون پروپرتی را به عنوان dependency property هم تعریف کنم ، باز هم همون ارور را میده :

C#:
        public static readonly DependencyProperty ButtonShapeProperty = DependencyProperty.Register("ButtonShape", typeof(Path), typeof(ShapeTextButton));
        
        
        public Path ButtonShape
        {
            get
            {
                return (Path)this.GetValue(ShapeTextButton.ButtonShapeProperty);
            }
            set
            {
                this.SetValue(ShapeTextButton.ButtonShapeProperty, value);
            }
        }
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
اون پروپرتی را به عنوان dependency property هم تعریف کنم ، باز هم همون ارور را میده :

C#:
        public static readonly DependencyProperty ButtonShapeProperty = DependencyProperty.Register("ButtonShape", typeof(Path), typeof(ShapeTextButton));
       
       
        public Path ButtonShape
        {
            get
            {
                return (Path)this.GetValue(ShapeTextButton.ButtonShapeProperty);
            }
            set
            {
                this.SetValue(ShapeTextButton.ButtonShapeProperty, value);
            }
        }
تعریف تون با کاری که در TemplateBinding انجام داده اید نمیخونه.
بالاخره این ButtonShape قراره مشخصه ای از کلاس ShapeTextButton باشه یا قراره یک کلاس باشه با یک مشخصه Margin؟
در TemplateBinding طوری باهاش رفتار کرده اید که انگار ButtonShape یک کلاس ئه و Margin مشخصه ای داخل اون.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
تعریف تون با کاری که در TemplateBinding انجام داده اید نمیخونه.
بالاخره این ButtonShape قراره مشخصه ای از کلاس ShapeTextButton باشه یا قراره یک کلاس باشه با یک مشخصه Margin؟
در TemplateBinding طوری باهاش رفتار کرده اید که انگار ButtonShape یک کلاس ئه و Margin مشخصه ای داخل اون.

سلامی مجدد
خیلی ممنون استاد
ButtonShape قراره یه پروپرتی ای از نوع Path باشه که این پروپرتی ، در درون کلاس ShapeTextButton باشه .
اعضای این پروپرتی را میخوام TemplateBinding کنم . به طبع ، چون از نوع Path هست ، عضوِ Margin و ... داره . یعنی عضو Margin و ... از این پروپرتی را میخوام TemplateBinding کنم .
 

the_king

مدیرکل انجمن
سلامی مجدد
خیلی ممنون استاد
ButtonShape قراره یه پروپرتی ای از نوع Path باشه که این پروپرتی ، در درون کلاس ShapeTextButton باشه .
اعضای این پروپرتی را میخوام TemplateBinding کنم . به طبع ، چون از نوع Path هست ، عضوِ Margin و ... داره . یعنی عضو Margin و ... از این پروپرتی را میخوام TemplateBinding کنم .
توضیحات و مثال های TemplateBinding رو ببینید. ازتون یک مشخصه میخواد که برای اون نوع شیء که برایش ControlTemplate توصیف می کنید (ShapeTextButton) تعریف شده باشه. ShapeTextButton مشخصه ای به نام "ButtonShape.Margin" نداره.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
توضیحات و مثال های TemplateBinding رو ببینید. ازتون یک مشخصه میخواد که برای اون نوع شیء که برایش ControlTemplate توصیف می کنید (ShapeTextButton) تعریف شده باشه. ShapeTextButton مشخصه ای به نام "ButtonShape.Margin" نداره.

خیلی ممنون استاد .
منظورتون اینه که TemplateBinding ، فقط بصورت مستقیم برای پروپرتی در یک کلاس بکار میره؟
یعنی اگه بخوایم برای اعضای اون پروپرتی (مثلا برای ButtonShape.Margin که پرسیدم) ، اون TemplateBinding را بکار ببریم ، نمیشه؟
در این صورت ، بجای TemplateBinding ، باید از Binding (و Mode ئه TemplatedParent) استفاده کنیم؟
 

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

بالا