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

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
ثانیا LogicalTreeHelper.GetChildren(parent) و <Cast<object به شما null نخواهند داد، اون شرط childrens == null هیچوقت برقرار نمیشه.

خیلی ممنون استاد .
چرا null نمیده هرگز؟
اگه المنتی نداشته باشه ، چی میده پس؟
ضمن اینکه نوع خروجی شو که گرفتم ، انگار EnamerableWraper هست که هر چی توی اینترنت چرخیدم ، همچین کلاسی ندیدم !

ثالثا شما IEnumerator رو اول در Count پیمایش کرده اید، دیگه اون IEnumerator مصرف شده، رسیده به تهش.
IEnumerator رو مستقیم نباید بکار ببرید، چون وقتی پیمایش اش رو انجام داد دیگه بر نمیگرده به شروع. اون Count موجب به پیمایش اش میشه و دیگه چیزی برای پیمایش در foreach نمیمونه. از ToArray یا ToList استفاده کنید تا به مجموعه تبدیل بشه.

چرا این جوری هه؟
این خاصیت چی هست که باعث شده IEnumerator ، فقط یکبار قابل پیمایش بشه و دیگه نتونه پیمایش انجام بده؟
ربطی که به کلاسی که IEnumerator را پیاده سازی کرد ، نداره ، داره؟
چون مثلا خیلی از کلاس ها مثل List<T> و ... هم IEnumerator<T> را پیاده سازی کردن ولی فقط یکبار پیمایش نمیشن .

تشکر استاد .
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
چرا null نمیده هرگز؟
متدی null بر میگردونه که در روالش باشه، در توضیحات متد ها هم اگر امکان برگردوندن null یا هر مقدار خاص دیگری باشه مشخص میشه که در فلان شرایط فرضا null بر میگردونه. مثلا توضیحات بخش Returns برای Path.GetExtension رو ببینید :
Returns
String
The extension of the specified path (including the period "."), or null, or Empty.
If path is null, GetExtension(String) returns null.
If path does not have extension information, GetExtension(String) returns Empty.​

اگه المنتی نداشته باشه ، چی میده پس؟
چیز خاصی نمیده، یک IEnumerable ای میده که چیزی توش نیست، شبیه وقتی که از یک آرایه خالی GetEnumerator بگیرید.
ضمن اینکه نوع خروجی شو که گرفتم ، انگار EnamerableWraper هست که هر چی توی اینترنت چرخیدم ، همچین کلاسی ندیدم !
EnumeratorWrapper یک کلاس private داخل LogicalTreeHelper ئه، استفاده خارجی نداره که توضیحات بخواد.
برای کسی که از مقدار خروجی استفاده می کنه کلاسی که IEnumerable رو پیاده سازی کرده اهمیتی نداره، مهم اینه که IEnumerable ئه.

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

ربطی که به کلاسی که IEnumerator را پیاده سازی کرد ، نداره ، داره؟
چون مثلا خیلی از کلاس ها مثل List<T> و ... هم IEnumerator<T> را پیاده سازی کردن ولی فقط یکبار پیمایش نمیشن .
ممکنه، اما الزاما خود کلاس تقصیری نداره، منبع داده تعیین کننده است، منبع داده ممکنه مثل لیست نباشه که بشه به اولش برگشت.
توضیحات مربوط به Reset رو ببینید، میگه ممکنه اصلا پیاده سازی نشه، قابل Reset نباشه :
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلی ممنون استاد . :rose:
استاد ، در پروژه ی پیوست شده (که ساده شده هست) که تمپلیت و استایل برای ToolTip در Resource ئه Window نوشته شده ، چرا برای CheckBox که Content ئه ToolTip ئه CheckBox ، از نوع TextBlock هست ، تمپلیت ای که براش بکار برده شد ، محتوایی رو نشون نمیده؟
اما برای اون دو تا دکمه که ToolTip شون متن ساده هست ، محتوا را نشون میده؟

مشکل از تمپلیت هه؟
اگه آره ، کدوم قسمت از تمپلیت؟
من که ContentPresenter را برای تمپلیتِ ToolTip بکار بردم . حالا چه Content ئه ContentPresenter را TemplateBinding کنیم یا نه ، فرقی نداره .
مشکل از کجاست؟
تشکر استاد .
 

the_king

مدیرکل انجمن
خیلی ممنون استاد . :rose:
استاد ، در پروژه ی پیوست شده (که ساده شده هست) که تمپلیت و استایل برای ToolTip در Resource ئه Window نوشته شده ، چرا برای CheckBox که Content ئه ToolTip ئه CheckBox ، از نوع TextBlock هست ، تمپلیت ای که براش بکار برده شد ، محتوایی رو نشون نمیده؟
اما برای اون دو تا دکمه که ToolTip شون متن ساده هست ، محتوا را نشون میده؟

مشکل از تمپلیت هه؟
اگه آره ، کدوم قسمت از تمپلیت؟
من که ContentPresenter را برای تمپلیتِ ToolTip بکار بردم . حالا چه Content ئه ContentPresenter را TemplateBinding کنیم یا نه ، فرقی نداره .
مشکل از کجاست؟
تشکر استاد .
من چیزی از پیوست تون نمی بینم.
 

the_king

مدیرکل انجمن
خیلی ممنون استاد . :rose:
استاد ، در پروژه ی پیوست شده (که ساده شده هست) که تمپلیت و استایل برای ToolTip در Resource ئه Window نوشته شده ، چرا برای CheckBox که Content ئه ToolTip ئه CheckBox ، از نوع TextBlock هست ، تمپلیت ای که براش بکار برده شد ، محتوایی رو نشون نمیده؟
اما برای اون دو تا دکمه که ToolTip شون متن ساده هست ، محتوا را نشون میده؟

مشکل از تمپلیت هه؟
اگه آره ، کدوم قسمت از تمپلیت؟
من که ContentPresenter را برای تمپلیتِ ToolTip بکار بردم . حالا چه Content ئه ContentPresenter را TemplateBinding کنیم یا نه ، فرقی نداره .
مشکل از کجاست؟
تشکر استاد .
اولا ControlTemplate تون دو تا ContentPresenter داره، یعنی چی؟ توقع نداشته باشید که یک المنت در دو جا همزمان نمایش داده بشه. اون متن ها در دو جا قابل نمایش هست، صرفا به این دلیل value type هستند و تکثیر میشن. TextBlock ئه که تکثیر نمیشه.
XML:
    <StackPanel>
        <StackPanel.Resources>
            <ControlTemplate x:Key="MyButton" TargetType="Button">
                <StackPanel Background="{TemplateBinding Background}">
                    <ContentPresenter/>
                    <ContentPresenter/>
                </StackPanel>
            </ControlTemplate>
        </StackPanel.Resources>
        <Button Background="Yellow" Template="{StaticResource MyButton}" Width="100" Height="70" >
            test
        </Button>
        <Button Background="Orange" Template="{StaticResource MyButton}" Width="100" Height="70" >
            <TextBlock>test</TextBlock>
        </Button>
    </StackPanel>
ثانیا در ToolTipsPlacementValueConverter شرط قرار داده اید که اگر Right یا Left یا Center بود true بشه، در Convert اش یک break point قرار بدهید و ببینید مقدار toolTipPlacementMode چیه، شرط برقرار هست که PlacementTriggerBorder ئه Visible بشه یا نه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
اولا ControlTemplate تون دو تا ContentPresenter داره، یعنی چی؟ توقع نداشته باشید که یک المنت در دو جا همزمان نمایش داده بشه. اون متن ها در دو جا قابل نمایش هست، صرفا به این دلیل value type هستند و تکثیر میشن. TextBlock ئه که تکثیر نمیشه.
XML:
    <StackPanel>
        <StackPanel.Resources>
            <ControlTemplate x:Key="MyButton" TargetType="Button">
                <StackPanel Background="{TemplateBinding Background}">
                    <ContentPresenter/>
                    <ContentPresenter/>
                </StackPanel>
            </ControlTemplate>
        </StackPanel.Resources>
        <Button Background="Yellow" Template="{StaticResource MyButton}" Width="100" Height="70" >
            test
        </Button>
        <Button Background="Orange" Template="{StaticResource MyButton}" Width="100" Height="70" >
            <TextBlock>test</TextBlock>
        </Button>
    </StackPanel>
ثانیا در ToolTipsPlacementValueConverter شرط قرار داده اید که اگر Right یا Left یا Center بود true بشه، در Convert اش یک break point قرار بدهید و ببینید مقدار toolTipPlacementMode چیه، شرط برقرار هست که PlacementTriggerBorder ئه Visible بشه یا نه.

خیلی ممنون استاد .
اما اون ContentPresenter ای که درون Border هست (همون ContentPresenter ئه دومی هه) ، بصورت عادی ، اون والدش که Border باشه ، نمایش اش را غیر فعال کردم . و فقط زمانی که مقدار پروپرتیِ Placement ، به یکی از 3 مقدارِ Right یا Left یا Center تغییر کنه ، نمایش اش فعال میشه (و در این صورت نمایش ContentPresenter ئه اصلی ام دوباره غیر فعال میشه) . در واقع ، در یک لحظه ، فقط یک ContentPresenter از اون دو تا Visiable هست فقط .

پس با اون حال (که فقط در یک لحظه ، فقط یک ContentPresenter از اون دو تا ، Visiable هست) ، چرا این طور میشه؟ (البته همونطور که گفتید ، از یه دونه ContentPresenter استفاده کردم و درست شد) .

تشکر استاد .
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
اما اون ContentPresenter ای که درون Border هست (همون ContentPresenter ئه دومی هه) ، بصورت عادی ، اون والدش که Border باشه ، نمایش اش را غیر فعال کردم . و فقط زمانی که مقدار پروپرتیِ Placement ، به یکی از 3 مقدارِ Right یا Left یا Center تغییر کنه ، نمایش اش فعال میشه (و در این صورت نمایش ContentPresenter ئه اصلی ام دوباره غیر فعال میشه) . در واقع ، در یک لحظه ، فقط یک ContentPresenter از اون دو تا Visiable هست فقط .

پس با اون حال (که فقط در یک لحظه ، فقط یک ContentPresenter از اون دو تا ، Visiable هست) ، چرا این طور میشه؟ (البته همونطور که گفتید ، از یه دونه ContentPresenter استفاده کردم و درست شد) .
ابهام تون در چیه؟ میدونید که اون TextBlock نمیتونه در هر دو ContentPresenter باشه، چه مخفی باشه و چه آشکار باشه به هر حال جای TextBlock صرفا در ContentPresenter دوم ئه. در اولی TextBlock ای نیست که مخفی و آشکار بودن ContentPresenter تاثیر داشته باشه.
 

SajjadKhati

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

استاد ، اگه در کنترل Xceed.Wpf.Toolkit.MessageBox :


اگه بخوام از حالت شی گرای این کلاس استفاده کنم :

C#:
            Xceed.Wpf.Toolkit.MessageBox messageBox = new Xceed.Wpf.Toolkit.MessageBox();
            messageBox.Text = "salam";
            messageBox.Caption = "my message";
            messageBox.OkButtonContent = "سلام";
            messageBox.WindowBackground = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
            messageBox.ShowDialog();

آیا در کد بالا میشه کدی نوشت که دکمه ی Yes (یا No) را هم اضافه کنه؟
در قسمت شی گرا ، پروپرتی ای برای این کار نمیبینم .
تشکر استاد .
 

the_king

مدیرکل انجمن
استاد ، اگه در کنترل Xceed.Wpf.Toolkit.MessageBox :


اگه بخوام از حالت شی گرای این کلاس استفاده کنم :

C#:
            Xceed.Wpf.Toolkit.MessageBox messageBox = new Xceed.Wpf.Toolkit.MessageBox();
            messageBox.Text = "salam";
            messageBox.Caption = "my message";
            messageBox.OkButtonContent = "سلام";
            messageBox.WindowBackground = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
            messageBox.ShowDialog();

آیا در کد بالا میشه کدی نوشت که دکمه ی Yes (یا No) را هم اضافه کنه؟
در قسمت شی گرا ، پروپرتی ای برای این کار نمیبینم .
تشکر استاد .
در #C چیزی جز شی گرایی وجود نداره، پس استفاده غیر شیء گرا بی معنیه، از هر چیزی استفاده کنید حالت شیء گرای داره.
طبق کدش برای تعیین وضعیت button ها باید از ShowMessageBox استفاده می کردید که داخلش پارامتر button داره.
وگرنه مشخصه ای نیست که مقدار فیلد button_ رو تغییر بده.

C#:
            var messageBox = new Xceed.Wpf.Toolkit.MessageBox();
            var fieldInfo = messageBox.GetType().GetField("_button", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            fieldInfo?.SetValue(messageBox, MessageBoxButton.YesNo);
            messageBox.Text = "salam";
            messageBox.Caption = "my message";
            messageBox.YesButtonContent = "بله";
            messageBox.NoButtonContent = "خیر";
            messageBox.WindowBackground = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
            messageBox.ShowDialog();
 

SajjadKhati

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

درون Resource :

XML:
    <Style TargetType="{x:Type ToolKit:MessageBox}">
        <Setter Property="SnapsToDevicePixels" Value="True"/>
        <Setter Property="WindowBackground" Value="Yellow"/>
    </Style>

و بعد این Resource (که درون DarkStyle هست) را به عنوان Style ئه Window استفاده کردم .
و در کد زیر در رویداد Loaded ئه Window ام :

C#:
        private void SettingWindow_Loaded(object sender, RoutedEventArgs e)
        {
            Style messageBoxStyle = Application.Current.TryFindResource(typeof(Xceed.Wpf.Toolkit.MessageBox)) as Style;
            Xceed.Wpf.Toolkit.MessageBox.Show(this, "salam", "my message", messageBoxStyle);
        }

اما WindowBackground ای که درون استایل رنگش را قرمز مشخص کرده بودم ، عمل نمیکنه (همون پیش فرضش آبی ملایم هست) .
متغییر messageBoxStyle هم مشکلی نداره و شی ای از نوع Style داره .
مشکل کجاست؟
 

the_king

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

درون Resource :

XML:
    <Style TargetType="{x:Type ToolKit:MessageBox}">
        <Setter Property="SnapsToDevicePixels" Value="True"/>
        <Setter Property="WindowBackground" Value="Yellow"/>
    </Style>

و بعد این Resource (که درون DarkStyle هست) را به عنوان Style ئه Window استفاده کردم .
و در کد زیر در رویداد Loaded ئه Window ام :

C#:
        private void SettingWindow_Loaded(object sender, RoutedEventArgs e)
        {
            Style messageBoxStyle = Application.Current.TryFindResource(typeof(Xceed.Wpf.Toolkit.MessageBox)) as Style;
            Xceed.Wpf.Toolkit.MessageBox.Show(this, "salam", "my message", messageBoxStyle);
        }

اما WindowBackground ای که درون استایل رنگش را قرمز مشخص کرده بودم ، عمل نمیکنه (همون پیش فرضش آبی ملایم هست) .
متغییر messageBoxStyle هم مشکلی نداره و شی ای از نوع Style داره .
مشکل کجاست؟
حالتون خوبه؟ WindowBackground رو Yellow مشخص کرده اید که Yellow هم قرمز نیست و مشکلی هم در اجرا نداره :
yellow.png
 

SajjadKhati

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

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

1.JPG

کد هم همونی هه که پست قبلی دادم .
همونطور هم که در تصویر زیر میبینید در break point ای که گذاشتم، متغییر messageBoxStyle ، مقداری از نوع Style داره و null نیست :

2.JPG

تشکر استاد .
 

SajjadKhati

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

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

کد هم همونی هه که پست قبلی دادم .
همونطور هم که در تصویر زیر میبینید در break point ای که گذاشتم، متغییر messageBoxStyle ، مقداری از نوع Style داره و null نیست :

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

تشکر استاد .

استاد ، جوابش را انگار پیدا کردم اما دلیلش را نمیدونم .
در کد :

C#:
Style messageBoxStyle = Application.Current.TryFindResource(typeof(Xceed.Wpf.Toolkit.MessageBox)) as Style;

بجای استفاده از متد Application.Current.TryFindResource ، از متد this.TryFindResource که استفاده میکنم ، مشکل حل میشه .
اما دلیلش چیه؟

خوب اولا style ئه Xceed.Wpf.Toolkit.MessageBox را درون Resource ئه DarkStyle نوشتم و این Resource را هم الحاق کردم (درون Resource ئه Window ، کد الحاق را نوشتم) . و بعد هم درون رویداد Load ئه اون Window و یا رویدادهای دکمه درون اون Window ، اون متد Application.Current.TryFindResource را استفاده میکنم که جواب نمیده .

و دوما با همون کد Application.Current.TryFindResource ، مقدار خروجیِ متغییرش ، یعنی مقدار متغییرِ messageBoxStyle ، شی ای از Style هست . یعنی null نیست . این متد اگه چیزی رو پیدا نمیکرد ، پس چرا مقدارش از نوع Style بود؟ اگه پیدا کرد ، چرا با این متد جواب نمیده (و فقط با متد this.TryFindResource جواب میده)؟

جالبش اینجاست که وقتی پروژه را کوچیک کردم و همین DarkStyle رو توی پروژه ی کوچیک تر منتقل کردم ، علاوه بر متد this.TryFindResource ، با متد Application.Current.TryFindResource هم جواب میده و مشکلی نداره!
دلیلش را نمیدونم!

تشکر استاد .
 

SajjadKhati

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

مثلا من برای تمپلیتِ MessageBox ، برای اون کنترلِ PART_WindowControl در کد زیر ، تقریبا همه ی پروپرتی های اون کلاسش را بایندینگ کردم (تا احیانا این پیش نیاد که پروپرتی ای بدون بایندینگ بمونه) :

C#:
    <ControlTemplate x:Key="MessageBoxTemplate" TargetType="{x:Type ToolKit:MessageBox}">
        <ToolKit:WindowControl Name="PART_WindowControl" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                               Background="{TemplateBinding Background}" Foreground="{TemplateBinding Foreground}"
                               BorderBrush="{TemplateBinding BorderBrush}" CaptionForeground="{TemplateBinding CaptionForeground}"
                               CaptionShadowBrush="{TemplateBinding CaptionShadowBrush}" WindowBackground="{TemplateBinding WindowBackground}"
                               WindowBorderBrush="{TemplateBinding WindowBorderBrush}" WindowInactiveBackground="{TemplateBinding WindowInactiveBackground}"
                               BorderThickness="{TemplateBinding BorderThickness}" WindowBorderThickness="{TemplateBinding WindowBorderThickness}"
                               WindowThickness="{TemplateBinding WindowThickness}"
                               HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}"
                               HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                               Margin="{TemplateBinding Margin}" Padding="{TemplateBinding Padding}"
                               Top="{TemplateBinding Top}" Left="{TemplateBinding Left}" IsActive="{TemplateBinding IsActive}"
                               CloseButtonVisibility="{TemplateBinding CloseButtonVisibility}" CaptionIcon="{TemplateBinding CaptionIcon}"
                               WindowStyle="{TemplateBinding WindowStyle}" CaptionFontSize="{TemplateBinding CaptionFontSize}"
                               Caption="{TemplateBinding Caption}" WindowOpacity="{TemplateBinding WindowOpacity}">
            <Grid Name="MainGrid" Background="Transparent">
                <Button Name="PART_OkButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  Width="100" Height="30"/>
            </Grid>
        </ToolKit:WindowControl>
    </ControlTemplate>

همین الان هم میدونم خیلی از این بایندینگ ها ضروری نیست و ممکنه اتوماتیک بایندینگ باشن اما نمیدونم از کجا تشخیص بدم که کدوم ها ضروری نیستن (و اتوماتیک بایندینگ میشن) تا کدِ بایندینگش را حذف کنم؟
مثلا پروپرتی width و height و اینها ، یکی از این موارد هست که نیاز به بایندینگ نداره اما نمیدونم برای پروپرتی های بالا ، چجوری تشخیص بدم؟

تشکر استاد .
 

the_king

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

مثلا من برای تمپلیتِ MessageBox ، برای اون کنترلِ PART_WindowControl در کد زیر ، تقریبا همه ی پروپرتی های اون کلاسش را بایندینگ کردم (تا احیانا این پیش نیاد که پروپرتی ای بدون بایندینگ بمونه) :

C#:
    <ControlTemplate x:Key="MessageBoxTemplate" TargetType="{x:Type ToolKit:MessageBox}">
        <ToolKit:WindowControl Name="PART_WindowControl" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                               Background="{TemplateBinding Background}" Foreground="{TemplateBinding Foreground}"
                               BorderBrush="{TemplateBinding BorderBrush}" CaptionForeground="{TemplateBinding CaptionForeground}"
                               CaptionShadowBrush="{TemplateBinding CaptionShadowBrush}" WindowBackground="{TemplateBinding WindowBackground}"
                               WindowBorderBrush="{TemplateBinding WindowBorderBrush}" WindowInactiveBackground="{TemplateBinding WindowInactiveBackground}"
                               BorderThickness="{TemplateBinding BorderThickness}" WindowBorderThickness="{TemplateBinding WindowBorderThickness}"
                               WindowThickness="{TemplateBinding WindowThickness}"
                               HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}"
                               HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                               Margin="{TemplateBinding Margin}" Padding="{TemplateBinding Padding}"
                               Top="{TemplateBinding Top}" Left="{TemplateBinding Left}" IsActive="{TemplateBinding IsActive}"
                               CloseButtonVisibility="{TemplateBinding CloseButtonVisibility}" CaptionIcon="{TemplateBinding CaptionIcon}"
                               WindowStyle="{TemplateBinding WindowStyle}" CaptionFontSize="{TemplateBinding CaptionFontSize}"
                               Caption="{TemplateBinding Caption}" WindowOpacity="{TemplateBinding WindowOpacity}">
            <Grid Name="MainGrid" Background="Transparent">
                <Button Name="PART_OkButton" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  Width="100" Height="30"/>
            </Grid>
        </ToolKit:WindowControl>
    </ControlTemplate>

همین الان هم میدونم خیلی از این بایندینگ ها ضروری نیست و ممکنه اتوماتیک بایندینگ باشن اما نمیدونم از کجا تشخیص بدم که کدوم ها ضروری نیستن (و اتوماتیک بایندینگ میشن) تا کدِ بایندینگش را حذف کنم؟
مثلا پروپرتی width و height و اینها ، یکی از این موارد هست که نیاز به بایندینگ نداره اما نمیدونم برای پروپرتی های بالا ، چجوری تشخیص بدم؟

تشکر استاد .
قبلا چند بار در این مورد سوال کرده اید و پاسخ دادم، وقتی دارید برای x یک Template یا Style طراحی می کنید باید به نمونه Template/Style پیشفرض در x مراجعه کنید.
طبعا هر چیزی که وجودش اهمیت داشته باشه در اون نمونه پیشفرض مشخص شده.
در Resources کمپوننت اش هم Style اش هست و هم ControlTemplate
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
بله . خیلی ممنون استاد .
استاد ، اگه همین کلاس Xceed.Wpf.Toolkit.MessageBox را بخوام بصورتی که متد Window.Show نمایش میده ، نمایش بدم ، راهی هست؟

یعنی میخوام وقتی Xceed.Wpf.Toolkit.MessageBox نمایش داده میشه ، در نخی که نخ اصلی ام هست ، نمایش نده . چون میخوام ازش به عنوان ویندوز برای هشدار و اینها استفاده کنم که نباید برنامه ی اصلی مو منتظر بذاره یا به برنامه و ویندوزِ اصلی ام ربط داشته باشه . یعنی مثل هشدارهایی که اغلبِ آنتی ویروس ها و یا خیلی از نرم افزارهای دیگه ، بصورت مستقل در کنار ساعت سیستم میدن (اینجوری) .

اما چون جد کلاس Xceed.Wpf.Toolkit.MessageBox ، کلاس ContentControl هست ، همونطور که میدونید کلا با ساخت نخ جدید (تا جایی که میدونم) و اجرای در اون نخ ، مشکل دارن . حالا نمیدونم ترفندی میشه زد که این رو در نخ جدیدی بدون مشکل نوشت؟
یا اینکه مجبورم یه کلاس Window برای این کار بنویسم؟
کلا اگه میشه کاری کرد ، نمیخوام کلاس Window ای طراحی کنم . چون Xceed.Wpf.Toolkit.MessageBox ، تقریبا 90 درصدِ اعضایی که برای این کار میخوام را با خودش داره و فقط میخوام یه کم تغییر بدم .

تشکر استاد .
 

the_king

مدیرکل انجمن
بله . خیلی ممنون استاد .
استاد ، اگه همین کلاس Xceed.Wpf.Toolkit.MessageBox را بخوام بصورتی که متد Window.Show نمایش میده ، نمایش بدم ، راهی هست؟

یعنی میخوام وقتی Xceed.Wpf.Toolkit.MessageBox نمایش داده میشه ، در نخی که نخ اصلی ام هست ، نمایش نده . چون میخوام ازش به عنوان ویندوز برای هشدار و اینها استفاده کنم که نباید برنامه ی اصلی مو منتظر بذاره یا به برنامه و ویندوزِ اصلی ام ربط داشته باشه . یعنی مثل هشدارهایی که اغلبِ آنتی ویروس ها و یا خیلی از نرم افزارهای دیگه ، بصورت مستقل در کنار ساعت سیستم میدن (اینجوری) .
تفاوت Show و ShowDialog در اون خصوصیت Modal یا Modeless بودن پنجره است، ارتباطی با نخ اصلی و فرعی نداره، دو تا مساله متفاوت هستند.
اون Xceed.Wpf.Toolkit.MessageBox داخل یک Window نمایش داده میشه که متد CreateContainer اش میسازه، تنها موردی که برای شما مشکل ایجاد میکنه اینه که اون پنجره با ShowDialog نمایش داده شده، شما می خواهید Show رو بجای ShowDialog فراخوانی کنید.

اما چون جد کلاس Xceed.Wpf.Toolkit.MessageBox ، کلاس ContentControl هست ، همونطور که میدونید کلا با ساخت نخ جدید (تا جایی که میدونم) و اجرای در اون نخ ، مشکل دارن . حالا نمیدونم ترفندی میشه زد که این رو در نخ جدیدی بدون مشکل نوشت؟
یا اینکه مجبورم یه کلاس Window برای این کار بنویسم؟
کلا اگه میشه کاری کرد ، نمیخوام کلاس Window ای طراحی کنم . چون Xceed.Wpf.Toolkit.MessageBox ، تقریبا 90 درصدِ اعضایی که برای این کار میخوام را با خودش داره و فقط میخوام یه کم تغییر بدم .
با MessageBox مشکل دارید چون میگید وارث کلاس ContentControl ئه، بعد به عنوان جایگزین از Window صحبت می کنید که اونم ContentControl ئه؟
اصلا قضیه Show و ShowDialog ربطی به نخ جدید نداره.
صرفا زمانی می توانید از پنجره Modeless استفاده کنید که یا MessageBoxResult اش براتون اهمیتی نداشته باشه (چون کد فراخوان منتظر دریافت مقدار بازگشتی نمیشه) یا اینکه متد هایی به رخداد های پنجره یا کنترل های داخلش متصل کنید تا تعامل کاربر با پنجره به اطلاع تون برسه.
C#:
            var messageBox = new Xceed.Wpf.Toolkit.MessageBox
            {
                Text = "Message",
                Caption = "Title",
                OkButtonContent = "Accept",
                Visibility = Visibility.Visible
            };
            var methodInfo = messageBox.GetType().GetMethod("CreateContainer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            var window = (Window)methodInfo?.Invoke(messageBox, null);
            window?.Show();
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
تفاوت Show و ShowDialog در اون خصوصیت Modal یا Modeless بودن پنجره است، ارتباطی با نخ اصلی و فرعی نداره، دو تا مساله متفاوت هستند.
اون Xceed.Wpf.Toolkit.MessageBox داخل یک Window نمایش داده میشه که متد CreateContainer اش میسازه، تنها موردی که برای شما مشکل ایجاد میکنه اینه که اون پنجره با ShowDialog نمایش داده شده، شما می خواهید Show رو بجای ShowDialog فراخوانی کنید.


با MessageBox مشکل دارید چون میگید وارث کلاس ContentControl ئه، بعد به عنوان جایگزین از Window صحبت می کنید که اونم ContentControl ئه؟
اصلا قضیه Show و ShowDialog ربطی به نخ جدید نداره.
صرفا زمانی می توانید از پنجره Modeless استفاده کنید که یا MessageBoxResult اش براتون اهمیتی نداشته باشه (چون کد فراخوان منتظر دریافت مقدار بازگشتی نمیشه) یا اینکه متد هایی به رخداد های پنجره یا کنترل های داخلش متصل کنید تا تعامل کاربر با پنجره به اطلاع تون برسه.
C#:
            var messageBox = new Xceed.Wpf.Toolkit.MessageBox
            {
                Text = "Message",
                Caption = "Title",
                OkButtonContent = "Accept",
                Visibility = Visibility.Visible
            };
            var methodInfo = messageBox.GetType().GetMethod("CreateContainer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            var window = (Window)methodInfo?.Invoke(messageBox, null);
            window?.Show();

سلام
خیلی ممنون استاد .
استاد ، کلاسی بنام AlarmBox تعریف کردم که از این کلاسِ Xceed.Wpf.Toolkit.MessageBox ارث بری میکنه .
حالا میخوام بدنه ی اعضایی که نیاز دارم را کپی کنم (تا طبق چیزی که گفتین ، از متد CreateContainer استفاده کنم) .
به همین منظور ، همونطور که میدونید ، یه متدی بنام ShowDialog در کلاسِ Xceed.Wpf.Toolkit.MessageBox هست که مقدار فیلدِ private ئه this._dialogResult را در بدنه ی این متد ، مقدار MessageBoxResult.None قرار میده .

حالا من میخوام به این فیلد ، دسترسی داشته باشم که کد زیر را در متد ShowModelessInstance که در کلاسِ AlarmBox تعریف کردم (و معادل ShowDialog در MessageBox هست) ، مینویسیم :

C#:
            FieldInfo _dialogResultFieldInfo = this.GetType().GetField("_dialogResult", BindingFlags.NonPublic | BindingFlags.Instance);
            object obj = _dialogResultFieldInfo?.GetValue(this);

اما متغییر _dialogResultFieldInfo ، مقدارش null میشه .
چرا؟
BindingFlags هایی که به کار بردم ، ظاهرا درستن . این طور نیست؟

تشکر استاد .
 

the_king

مدیرکل انجمن
سلام
خیلی ممنون استاد .
استاد ، کلاسی بنام AlarmBox تعریف کردم که از این کلاسِ Xceed.Wpf.Toolkit.MessageBox ارث بری میکنه .
حالا میخوام بدنه ی اعضایی که نیاز دارم را کپی کنم (تا طبق چیزی که گفتین ، از متد CreateContainer استفاده کنم) .
به همین منظور ، همونطور که میدونید ، یه متدی بنام ShowDialog در کلاسِ Xceed.Wpf.Toolkit.MessageBox هست که مقدار فیلدِ private ئه this._dialogResult را در بدنه ی این متد ، مقدار MessageBoxResult.None قرار میده .

حالا من میخوام به این فیلد ، دسترسی داشته باشم که کد زیر را در متد ShowModelessInstance که در کلاسِ AlarmBox تعریف کردم (و معادل ShowDialog در MessageBox هست) ، مینویسیم :

C#:
            FieldInfo _dialogResultFieldInfo = this.GetType().GetField("_dialogResult", BindingFlags.NonPublic | BindingFlags.Instance);
            object obj = _dialogResultFieldInfo?.GetValue(this);

اما متغییر _dialogResultFieldInfo ، مقدارش null میشه .
چرا؟
BindingFlags هایی که به کار بردم ، ظاهرا درستن . این طور نیست؟

تشکر استاد .
مشکل از BindingFlags نیست، از ()GetType ئه. کلاسی که شما ساخته اید خودش که فیلد private ای به نام dialogResult_ نداره، وارث کلاسی است که اون فیلد رو داره. فیلد private هم که در وراثت دخالتی نداره.
به جای ()GetType از typeof(Xceed.Wpf.Toolkit.MessageBox) استفاده کنید.
 

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

بالا