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

the_king

مدیرکل انجمن
خیلی ممنون استاد :rose:
آها ، یعنی با ساختنِ Attached Property ، میتونیم داخلِ این نوع پروپرتی (داخل Attached Property) ، مقدار سِت کنیم؟
باز این روش ، خیلی آسون تر از اون روشی هست که من پیدا کرده بودم (در پست قبل) . البته یه مشکل کوچیکش اینه که از کدهای سی شارپ هم استفاده میشه که حالا میشه نادیده اش گرفت .
استفاده از کد #C که ایراد یا امتیاز منفی محسوب نمیشه. اینکه کدی ننویسید رو برای خودتون چالش نکنید، فقط خودتون رو به زحمت می اندازید.


استاد ، تمپلیت ای که برای همین کنترل (DoubleUpDown) نوشتم و در این پست پیوست میکنم ، دو تا مشکل داره :

XML:
        <ToolKit:DoubleUpDown Name="numUpDown" Style="{StaticResource DoubleUpDownStyle}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="20,20,0,0" Width="100" Height="36" Background="#FF5F5F5F" Value="10" BorderBrush="White" Foreground="White" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
اول اینکه وقتی در قسمت Trigger ئه اون تمپلیتِ DoubleUpDownStyle ، برای IsFocused ، اون تریگر را مینویسم ، زمانی که روی اون کنترل فوکوس انجام میشه ، اجرا نمیشه . اما اگه برای کنترل TextBox ای که داخلِ اون تمپلیت هست ، شرط بذارم ، اجرا میشه . مشکل تریگر در تمپلیت چیه که وقتی روی IsFocused ئه کنترل DoubleUpDown شرط میذارم ، اجرا نمیشه؟
روال عادی IsFocused طوریه که باید مشخص کنه که کدوم المنت Focus رو دریافت کرده، از اونجایی که Focus نمیتونه همزمان در چند جا باشه نمیشه که هم TextBox ئه Focus بگیره و هم اون المنتی که والد TextBox ئه است، حتی اگه والد امکان Focus گرفتن رو داشته باشه با این وجود Focus رو فرزند تصاحب کرده و والد Focus نداره.
XML:
    <Grid>
        <Grid.Resources>
            <ControlTemplate TargetType="Button" x:Key="MyButtonTemplate">
                <Grid>
                    <Button Width="100" Height="50" HorizontalAlignment="Left" VerticalAlignment="Center"/>
                    <Button Width="100" Height="50" HorizontalAlignment="Right" VerticalAlignment="Center"/>
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"></ContentPresenter>
                </Grid>
            </ControlTemplate>
            <Style TargetType="Button">
                <Style.Triggers>
                    <Trigger Property="IsFocused" Value="True">
                        <Setter Property="Content" Value="Focused: True"/>
                    </Trigger>
                    <Trigger Property="IsFocused" Value="False">
                        <Setter Property="Content" Value="Focused: False"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Grid.Resources>
        <Button Width="300" Height="50" HorizontalAlignment="Center" VerticalAlignment="Center" Template="{StaticResource MyButtonTemplate}"/>
    </Grid>
دوم اینکه وقتی که از همین کنترل DoubleUpDown شی بسازید (منظورم همین داخلxaml هست) ، اگه این تمپلیت را بکار نبرید ، زمان اجرای برنامه ، وقتی که داخل بخشِ TextBox ئه DoubleUpDown کلیک کنید (یا کلا فوکوسی روش انجام بشه) و بعد دکمه ی بالا (فِلِش بالا) یا دکمه ی پایین (فِلِشِ پایین) در کیبرد رو بزنید ، اعداد کم یا زیاد میشن اما وقتی این تمپلیت را بکار ببرید ، این قابلیت رو دیگه نداره .
مشکل این از کجاست؟
مشکل از اینجا است که مطابق Style خودش پیش نرفته اید، وقتی میخواهید برای کنترلی Style بسازید اول باید بررسی کنید و ببینید خود Style پیشفرض اش چه مواردی داره، چه تنظیماتی داره. مثلا در Style دست ساز شما ممکنه رخداد های لازم به متد های مربوطه متصل نشده، Style خودش رو بررسی کنید تا ببینید چه مواردی رو از قلم انداخته اید، مثلا ممکنه EventSetter ای باشه که شما هم باید در Style داشته باشید.
 

SajjadKhati

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


که مثال style و تمپلیت ای براش نزد .
نمیشه از جور دیگه متوجه شد که Style پیشفرض اش چه موارد و تنظیماتی داره؟
 

the_king

مدیرکل انجمن
خیلی ممنون استاد (همچنین درباره ی جواب بخش اول) .
اسنادی که درباره ی اون کنترل DoubleUpDown هست ، فقط همین قدری هست که در لینکه زیر هست (حداقل ، من چیز بیشتری پیدا نکردم) :


که مثال style و تمپلیت ای براش نزد .
نمیشه از جور دیگه متوجه شد که Style پیشفرض اش چه موارد و تنظیماتی داره؟
از ابزار های مربوطه استفاده کنید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
در کد #C که نباید کد XAML باشه. در Resources هایش دنبال فایل های BAML بگردید.
خیلی ممنون استاد .
توی resource اش ، خیلی فایل baml هست . نزدیک به 50 فایل میشه . نام خاصی نداره؟ نمیدونید باید دنبال کدوم فایل baml بگردم؟
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
توی resource اش ، خیلی فایل baml هست . نزدیک به 50 فایل میشه . نام خاصی نداره؟ نمیدونید باید دنبال کدوم فایل baml بگردم؟
اطلاعی ندارم. کد متد سازنده کلاس رو برای فراخوانی یک فایل xaml بررسی کنید، احتمالا baml اش همنام اونه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
اطلاعی ندارم. کد متد سازنده کلاس رو برای فراخوانی یک فایل xaml بررسی کنید، احتمالا baml اش همنام اونه.
خیلی ممنون استاد .
شبیه ترین فایلی که به این قضیه میخورد ، فایل CalculatorUpDown/theme/aero2.NormalColor.baml بود که کلاس CalculatorUpDown با کلاس DoubleUpDown ، در اجداد با هم مشترک میشن .
کدی که یه کم به این قضیه ی کیبرد بخوره ، کد زیر بود :

XML:
            <Trigger Property="UIElement.IsFocused" Value="True">
              <Setter TargetName="PART_TextBox" Value="{Binding ElementName=PART_TextBox}" Property="FocusManager.FocusedElement" />
            </Trigger>
که توی ControlTemplate گذاشتم اما فرقی نکرد .

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

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

XML:
<Trigger Property="UIElement.IsKeyboardFocusWithin" Value="True">
              <Setter Value="{DynamicResource {x:Static themes:ResourceKeys.ControlSelectedBorderKey}}" Property="Control.BorderBrush" />
            </Trigger>
باید روی IsKeyboardFocusWithin تریگر گذاشته میشد .
 

SajjadKhati

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

XML:
<Trigger Property="UIElement.IsKeyboardFocusWithin" Value="True">
              <Setter Value="{DynamicResource {x:Static themes:ResourceKeys.ControlSelectedBorderKey}}" Property="Control.BorderBrush" />
            </Trigger>
باید روی IsKeyboardFocusWithin تریگر گذاشته میشد .
استاد ، چجوری هه که Binding را میشه برای پروپرتیِ Value انجام داد اما برای پروپرتیِ Property که بخوایم Binding رو استفاده کنیم ، ارور میده و میگه که Binding باید برای پروپرتی ای که DependencyProperty باشه و هم اون پروپرتی ، عضو کلاس DependencyObject باشه باید بکار برده بشه و واسه ی همین نمیشه در DependencyObject بکار برده بشه .

اگه این طور هه، پروپرتیِ Value هم نه DependencyProperty و هم نه اینکه کلاسش که کلاسِ Setter هست ، از نوعِ DependencyObject نیست و ازش ارث بری نکرد .
چجوری هه قضیه اش؟!
 

the_king

مدیرکل انجمن
استاد ، چجوری هه که Binding را میشه برای پروپرتیِ Value انجام داد اما برای پروپرتیِ Property که بخوایم Binding رو استفاده کنیم ، ارور میده و میگه که Binding باید برای پروپرتی ای که DependencyProperty باشه و هم اون پروپرتی ، عضو کلاس DependencyObject باشه باید بکار برده بشه و واسه ی همین نمیشه در DependencyObject بکار برده بشه .

اگه این طور هه، پروپرتیِ Value هم نه DependencyProperty و هم نه اینکه کلاسش که کلاسِ Setter هست ، از نوعِ DependencyObject نیست و ازش ارث بری نکرد .
چجوری هه قضیه اش؟!
Setter میخواد مقدار مشخصه x رو روی مقداری قرار بده. حالا این مقدار میتونه صریحا تعیین شده باشه، مثلا x = 4 یا میتونه منبع دیگری باشه، مثلا x = y
وقتی شما برای اشاره به Value از Binding استفاده می کنید، یعنی مقدار x رو متصل می کنید به منبع فلان که بر اساس اینکه مقدار منبع چی باشه مقدار x هم تغییر کنه. یعنی بجای اینکه بگید x = 4 میگید x = y.
اما اینکه مشخصه x رو Binding کنید یعنی چی؟ یعنی ? که نمیدونم چه مشخصه ای رو میخوام در Setter عوض کنم به 4 = ? یا y = ?، میخوام بر اساس فلان منبع تصمیم بگیرم قراره مقدار چه مشخصه ای عوض بشه. نمیدونم میخوام مقدار Width رو تعیین کنم یا Height یا Background. میشه همچین چیزی؟
اصلا این Setter چه معنی ای داره که نویسنده اش خودش نمیدونه میخواسته مقدار چه مشخصه ای رو تغییر بده؟
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
Setter میخواد مقدار مشخصه x رو روی مقداری قرار بده. حالا این مقدار میتونه صریحا تعیین شده باشه، مثلا x = 4 یا میتونه منبع دیگری باشه، مثلا x = y
وقتی شما برای اشاره به Value از Binding استفاده می کنید، یعنی مقدار x رو متصل می کنید به منبع فلان که بر اساس اینکه مقدار منبع چی باشه مقدار x هم تغییر کنه. یعنی بجای اینکه بگید x = 4 میگید x = y.
اما اینکه مشخصه x رو Binding کنید یعنی چی؟ یعنی ? که نمیدونم چه مشخصه ای رو میخوام در Setter عوض کنم به 4 = ? یا y = ?، میخوام بر اساس فلان منبع تصمیم بگیرم قراره مقدار چه مشخصه ای عوض بشه. نمیدونم میخوام مقدار Width رو تعیین کنم یا Height یا Background. میشه همچین چیزی؟
اصلا این Setter چه معنی ای داره که نویسنده اش خودش نمیدونه میخواسته مقدار چه مشخصه ای رو تغییر بده؟
خیلی ممنون استاد . :rose:
منظورم اینه که از لحاظ قواعد جلو بریم ، روی پروپرتیِ Value نباید بتونیم Binding انجام بدیم . چون نه این پروپرتی DependencyProperty هست و نه کلاسی که در اون قرار داره (یعنی کلاس Setter) ، کلاسی از نوع DependencyObject هست .
همونطور که موقع Binding کردنِ پروپرتیِ Property در این کلاس ، به همین دلایل گیر میده ، چرا به همین دلایل ، برای پروپرتیِ Value گیر نمیده؟

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

استاد ، ContentPresenter در کد زیر ، چرا کار نمیکنه؟ :

XML:
        <Style x:Key="radioButtonStyle" TargetType="{x:Type RadioButton}">
            <Setter Property="SnapsToDevicePixels" Value="True"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <BulletDecorator Background="{TemplateBinding Background}">
                            <BulletDecorator.Bullet>
                                <Grid Width="16" Height="16">
                                    <Ellipse Name="borderEllipse" StrokeThickness="1" Stroke="{TemplateBinding BorderBrush}" />
                                    <Ellipse Name="checkEllipse" Margin="4" Fill="{TemplateBinding BorderBrush}" Visibility="Hidden"/>
                                </Grid>
                            </BulletDecorator.Bullet>
                            <BulletDecorator.Child>
                                <ContentPresenter Name="radioButtonContent" TextBlock.Foreground="{TemplateBinding Foreground}" Margin="4,0,0,0"  RecognizesAccessKey="True"/>
                            </BulletDecorator.Child>
                        </BulletDecorator>
                       
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
مثال :

XML:
        <RadioButton Style="{StaticResource radioButtonStyle}" Content="test radio button" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="300,100,0,0" Background="Transparent" BorderBrush="#FFF9F9F9" Foreground="White" Height="28" Width="130"/>
تشکر استاد
 

the_king

مدیرکل انجمن
منظورم اینه که از لحاظ قواعد جلو بریم ، روی پروپرتیِ Value نباید بتونیم Binding انجام بدیم . چون نه این پروپرتی DependencyProperty هست و نه کلاسی که در اون قرار داره (یعنی کلاس Setter) ، کلاسی از نوع DependencyObject هست.
شما قواعد Setter رو در نظر گرفته اید؟ وقتی می نویسید Setter Property=x Value=4 یعنی در Setter ئه Value بشود 4 و Property بشود x؟ یا اینکه x بشود 4؟ آن چیزی که مقدارش 4 می شود Value است یا x ؟

همونطور که موقع Binding کردنِ پروپرتیِ Property در این کلاس ، به همین دلایل گیر میده ، چرا به همین دلایل ، برای پروپرتیِ Value گیر نمیده؟
روی Value که Binding نمی کنید، روی اون مشخصه ای که در Property تعیین شده Binding می کنید. Setter که خودش استفاده ای برای Value نداره که رویش چیزی رو Binding کنیم، Setter میخواد اون مقدار Value رو برای مشخصه ای تعیین کنه. اگر برای Value منبعی Binding کنید روی اون مشخصه که Property مشخصش می کنه Binding کرده اید، نه خود Value


استاد ، ContentPresenter در کد زیر ، چرا کار نمیکنه؟ :

XML:
        <Style x:Key="radioButtonStyle" TargetType="{x:Type RadioButton}">
            <Setter Property="SnapsToDevicePixels" Value="True"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <BulletDecorator Background="{TemplateBinding Background}">
                            <BulletDecorator.Bullet>
                                <Grid Width="16" Height="16">
                                    <Ellipse Name="borderEllipse" StrokeThickness="1" Stroke="{TemplateBinding BorderBrush}" />
                                    <Ellipse Name="checkEllipse" Margin="4" Fill="{TemplateBinding BorderBrush}" Visibility="Hidden"/>
                                </Grid>
                            </BulletDecorator.Bullet>
                            <BulletDecorator.Child>
                                <ContentPresenter Name="radioButtonContent" TextBlock.Foreground="{TemplateBinding Foreground}" Margin="4,0,0,0"  RecognizesAccessKey="True"/>
                            </BulletDecorator.Child>
                        </BulletDecorator>
                     
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
مثال :

XML:
        <RadioButton Style="{StaticResource radioButtonStyle}" Content="test radio button" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="300,100,0,0" Background="Transparent" BorderBrush="#FFF9F9F9" Foreground="White" Height="28" Width="130"/>
اولا نوع ControlTemplate مشخص نیست، ثانیا امیدوارم برای زمینه پشت اش رنگی جز رنگ پیشفرض سفید رو بکار برده باشید وگرنه Foreground سفید روی زمینه Transparent که زیرش هم سفید باشه دیده نمیشه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
شما قواعد Setter رو در نظر گرفته اید؟ وقتی می نویسید Setter Property=x Value=4 یعنی در Setter ئه Value بشود 4 و Property بشود x؟ یا اینکه x بشود 4؟ آن چیزی که مقدارش 4 می شود Value است یا x ؟


روی Value که Binding نمی کنید، روی اون مشخصه ای که در Property تعیین شده Binding می کنید. Setter که خودش استفاده ای برای Value نداره که رویش چیزی رو Binding کنیم، Setter میخواد اون مقدار Value رو برای مشخصه ای تعیین کنه. اگر برای Value منبعی Binding کنید روی اون مشخصه که Property مشخصش می کنه Binding کرده اید، نه خود Value
سلامی مجدد
خیلی ممنون استاد :rose:
پس چرا موقعِ Binding ، به پروپرتیِ Property (در کلاس Setter) گیر میده؟
خوب اگه روی اون پروپرتی ای که (به عنوان مقدار) ، به پروپرتیِ Property میدیم (مثلا Background ئه یه Border ای) ، Binding انجام میشه ، چرا به همون پروپرتی (مثلا همون Background ئه Border که Binding کرده بودیم) گیر نمیده که مثلا DependencyProperty نیست یا در کلاسی وجود نداره که از نوع DependencyObject هه؟
ولی (مستقیما) به پروپرتیِ Property گیر میده؟

اولا نوع ControlTemplate مشخص نیست، ثانیا امیدوارم برای زمینه پشت اش رنگی جز رنگ پیشفرض سفید رو بکار برده باشید وگرنه Foreground سفید روی زمینه Transparent که زیرش هم سفید باشه دیده نمیشه.
خیلی ممنون استاد . بله .
فراموش کردم نوع TargetType را در ControlTemplate مشخص کنم .

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

استاد ، توی Template ئه TabControl :


حداقل به 2 چیز (تگ و شی) نیاز اساسی هست تا کنترل TabControl کار کنه و بخش های اساسی اش نمایش داده بشه .
یکی که همون ContentPresenter بود که مشخص کردن در اون جدول (تا محتوای TabItem ای که کاربر انتخاب کرد را نشون بده) .
اما یکی دیگه ، به ItemsPresenter یا بهتر از اون ، به TabPanel برای نمایش خودِ TabItem (هِدِرها) نیاز هست که بصورت مستقیم در جدول نگفت و صرفا در مثال ها یا در توضیحاتش بصورت غیر مستقیم اشاره شد .

و اینکه استاد ، چرا ContentSource ئه ContentPresenter را در جاهای دیگه مثل ComboBoxItem لازم نبود مشخص کنیم اما در زمانی که برای TabItem استایل مینویسم ، لازمه؟


دوم اینکه وقتی که از همین کنترل DoubleUpDown شی بسازید (منظورم همین داخلxaml هست) ، اگه این تمپلیت را بکار نبرید ، زمان اجرای برنامه ، وقتی که داخل بخشِ TextBox ئه DoubleUpDown کلیک کنید (یا کلا فوکوسی روش انجام بشه) و بعد دکمه ی بالا (فِلِش بالا) یا دکمه ی پایین (فِلِشِ پایین) در کیبرد رو بزنید ، اعداد کم یا زیاد میشن اما وقتی این تمپلیت را بکار ببرید ، این قابلیت رو دیگه نداره .
مشکل این از کجاست؟
استاد ، میگم مشکل این قضیه ، با استفاده کردن از Attached Property های کلاس KeyboardNavigation حل نمیشه؟
چون توی TabControl ، خیلی از Attached Property های این کلاس استفاده شد .
اگه آره ، با کدوم Attached Property ئه این کلاس؟

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

the_king

مدیرکل انجمن
پس چرا موقعِ Binding ، به پروپرتیِ Property (در کلاس Setter) گیر میده؟
موقع Binding یعنی کد با موفقیت کامپایل شده باشه و موقع اجرای Setter بخواد Binding انجام بده، کد خطای زمان کامپایل نمیده؟ Setter با موفقیت کامپایل شدنی است که حالا بخواد به زمان Binding اش برسه؟

خوب اگه روی اون پروپرتی ای که (به عنوان مقدار) ، به پروپرتیِ Property میدیم (مثلا Background ئه یه Border ای) ، Binding انجام میشه.
، چرا به همون پروپرتی (مثلا همون Background ئه Border که Binding کرده بودیم) گیر نمیده که مثلا DependencyProperty نیست یا در کلاسی وجود نداره که از نوع DependencyObject هه
خطای مقدار غیر قابل قبول برای Property در Setter ئه، ربطی به مشخصه ای که میخواهید مقدارش رو بجای Property غالب کنید نداره.

ولی (مستقیما) به پروپرتیِ Property گیر میده؟
مقدار غیر قابل قبول برای Property نوشته اید، پس به چی گیر بده؟

و اینکه استاد ، چرا ContentSource ئه ContentPresenter را در جاهای دیگه مثل ComboBoxItem لازم نبود مشخص کنیم اما در زمانی که برای TabItem استایل مینویسم ، لازمه؟
اینکه چی لازم هست و چی لازم نیست رو طراحی کلاس مشخص میکنه. در ComboBoxItem آیتم نمایش داده میشه، ولی در TabControl عنوان و محتوای صفحه دو بخش مجزا است و TabItem قرار نیست محتوای صفحه Tab رو نمایش بده، محتوای صفحه در TabPanel نمایش داده میشه و در TabItem صرفا عنوان اش نمایش داده میشه، برای همین عنوان رو با نامی مثل Header از SelectedContent که محتوای صفحه انتخاب شده است تفکیک کرده اند.
چرا اش به طراحی کنترل اش مربوطه.

استاد ، میگم مشکل این قضیه ، با استفاده کردن از Attached Property های کلاس KeyboardNavigation حل نمیشه؟
چون توی TabControl ، خیلی از Attached Property های این کلاس استفاده شد .
اگه آره ، با کدوم Attached Property ئه این کلاس؟
مشکل قضیه رو قبلا بهتون گفتم، طبق روال Style پیشفرض هر کنترلی پیش بروید تا مشکلی پیش نیاد. در Style پیشفرض اگر از KeyboardNavigation استفاده کرده طبق همون مشخصات استفاده کنید، اگر نکرده، پس لازم نبوده.
 

SajjadKhati

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

مشکل قضیه رو قبلا بهتون گفتم، طبق روال Style پیشفرض هر کنترلی پیش بروید تا مشکلی پیش نیاد. در Style پیشفرض اگر از KeyboardNavigation استفاده کرده طبق همون مشخصات استفاده کنید، اگر نکرده، پس لازم نبوده.
همونطور که در پست 408 گفتم ، کد زیر در استایل اش نوشته بود :
XML:
            <Trigger Property="UIElement.IsFocused" Value="True">
              <Setter TargetName="PART_TextBox" Value="{Binding ElementName=PART_TextBox}" Property="FocusManager.FocusedElement" />
            </Trigger>
اما وقتی از این کد ، در کد xaml ام استفاده کردم ، فرقی نکرد و درست نشد .

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

استاد ، اگه در کلاسِ TabPanel (که از این کلاس برای نمایش tab Item ها در تمپلیت tab control استفاده کردم) ، بخوام وقتی کاربر ، فوکوس ای روی این TabPanel انجام داد (چه با موس ، وقتی که روی این کنترل ، هر نوع کلیکی کرد . نه صرفا وارد کنترل بشه و چه با کیبرد فوکوس کرده باشه) ، تریگر ای بنویسم ، باید روی کدوم پروپرتی شرط بذارم؟
روی پروپرتیِ Focuse شرط میذارم اما Setter ای که تعریف کرده بودم ، اجرا نمیشه :

XML:
        <Style x:Key="tabControlStyle" TargetType="{x:Type TabControl}">
            <Setter Property="SnapsToDevicePixels" Value="True"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabControl}">
                        <Grid KeyboardNavigation.TabNavigation="Local">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="*"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>


                            <Border Name="tabItemsBorder" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3" Grid.RowSpan="1" Background="{TemplateBinding Background}" BorderThickness="1" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="2">
                                <TabPanel Name="tabItemsPanel" Background="Transparent" IsItemsHost="True" Margin="1" Panel.ZIndex="1" KeyboardNavigation.TabIndex="1"/>
                            </Border>

                            <Border Name="tabContainerBorder" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="3" Grid.RowSpan="1" KeyboardNavigation.TabNavigation="Local" KeyboardNavigation.DirectionalNavigation="Contained" KeyboardNavigation.TabIndex="2" BorderThickness="1" BorderBrush="Green" Background="#FF9E9E9E">
                                <ScrollViewer Name="tabContainerScrollViewer" CanContentScroll="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" >
                                    <ContentPresenter Name="PART_SelectedContentHost" Margin="0" ContentSource="SelectedContent"/>
                                </ScrollViewer>
                            </Border>
                        </Grid>
                       
                        <ControlTemplate.Triggers>
                                                    <Trigger SourceName="tabItemsPanel" Property="IsFocused" Value="True">
                                <Setter TargetName="tabItemsBorder" Property="BorderBrush" Value="Red"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
تشکر استاد :rose:
 

the_king

مدیرکل انجمن
همونطور که در پست 408 گفتم ، کد زیر در استایل اش نوشته بود :
XML:
            <Trigger Property="UIElement.IsFocused" Value="True">
              <Setter TargetName="PART_TextBox" Value="{Binding ElementName=PART_TextBox}" Property="FocusManager.FocusedElement" />
            </Trigger>
اما وقتی از این کد ، در کد xaml ام استفاده کردم ، فرقی نکرد و درست نشد .
یکبار دقیقا کپی Style پیشفرض رو خودتون بنویسید و اعمال کنید و بعد که با اون Style نتیجه گرفتید یا نوشته قبلی خودتون مقایسه کنید.

استاد ، اگه در کلاسِ TabPanel (که از این کلاس برای نمایش tab Item ها در تمپلیت tab control استفاده کردم) ، بخوام وقتی کاربر ، فوکوس ای روی این TabPanel انجام داد (چه با موس ، وقتی که روی این کنترل ، هر نوع کلیکی کرد . نه صرفا وارد کنترل بشه و چه با کیبرد فوکوس کرده باشه) ، تریگر ای بنویسم ، باید روی کدوم پروپرتی شرط بذارم؟
مطالب قبلی رو در مورد Focus مجددا مرور کنید، ببینید وقتی در اون TabPanel دکمه ای هست و روی اون دکمه کلیک میشه Focus رو کدوم المنت تصاحب می کنه، Button یا یکی از والدین اش؟
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
یکبار دقیقا کپی Style پیشفرض رو خودتون بنویسید و اعمال کنید و بعد که با اون Style نتیجه گرفتید یا نوشته قبلی خودتون مقایسه کنید.
سلام استاد .
خیلی ممنون استاد .
در رویداد GotFocus ئه DoubleUpDown (که تمپلیت را بکار بردم)، با پروپرتیِ Keyboard.FocusedElement ، المنت ای که فوکوس میشه را گرفتم (کد تمپلیت را در زیر پیوست میکنم) .
وقتی روی این کنترلِ DoubleUpDown ، فوکوس میکنم ، در 3 المنت از تمپلیت ، فوکوس میکنه (که رفع ماجرای این قضیه که فقط روی یک المنت در تمپلیت فوکوس کنه هم انگار داستانه) .

اولین بار با فوکوس روی این کنترل DoubleUpDown ، روی المنتِ PART_TextBox فوکوس میکنه . وقتی روی این المنت فوکوس کنه ، با فشردن کلیدهای فِلِش بالا و پایین در کیبرد (Arrow up _ down) ، هیچ اتفاقی نمیافته (یعنی با فشردن کلید فلش بالا یا پایین کیبرد ، عددِ درونِ همین textbox ، کم یا زیاد نمیشه) .

وقتی دوباره کلید Tab کیبرد را میزنم ، فوکوس روی المنتِ PART_IncreaseButton که در تمپلیت وجود داره ، میره . حالا با فوکوس بودن روی این المنت ، اگه کلیدهای فِلِش بالا و پایین در کیبرد را فشار بدم ، عدد در اون textbox ، کم یا زیاد میشه و کار میکنه .

باز دوباره کلید tab را بزنم ، فوکوس روی المنتِ PART_DecreaseButton که در تمپلیت وجود داره ، میره . قضیه ی این هم مثل قضیه ی فوکوس روی PART_IncreaseButton هست (یعنی با فشردن فلش ها ، اعداد تغییر میکنن و کار میکنه) .

خوب حالا اینجا چند تا مشکل وجود داره :
اینو بگم که خوب میشه Focusable ئه یکی از PART_DecreaseButton یا PART_IncreaseButton را False کرد تا علی الحساب ، فوکوس شدن یه المنت ، کمتر بشه اما :
1) باز هم مشکل اینه که در این تمپلیت ، 2 تا المنت فوکوس میشن . یکی PART_TextBox و یکی دیگه هم PART_IncreaseButton (فرضا Focusable ئه PART_DecreaseButton را False کنم) .

2) اگه Focusable ئه PART_TextBox را False کنم ، بخش TextBox قابلیت فوکوس نخواهد داشت و نمیشه کاربر عدد مورد نظرش را وارد کنه (عملا Read Only میشه) . پس Focusable ئه PART_TextBox قطعا باید True بمونه .

3) اگه Focusable ئه PART_IncreaseButton را False کنم ، دیگه اون قضیه ی کیبرد (با فشردن فلش کیبرد ، اعداد تغییر میکردن) ، دیگه کار نمیکنه .

حالا سئوال اینجاست که چی کار کنم که هم این قضیه ی کیبرد کار کنه (تا اینجا انگار راهش اینه که فوکوس روی PART_IncreaseButton باشه) و هم توی کل تمپلیت ، فوکوس فقط روی یک المنت اش اتفاق بیافته (جوری که کاربر بتونه عدد رو توی TextBox وارد کنه) ؟

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

پیوست ها

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
مطالب قبلی رو در مورد Focus مجددا مرور کنید، ببینید وقتی در اون TabPanel دکمه ای هست و روی اون دکمه کلیک میشه Focus رو کدوم المنت تصاحب می کنه، Button یا یکی از والدین اش؟
این قضیه را متوجه شدم .
اما یه سئوال دیگه اینکه الان در کد زیر :

XML:
        <Style x:Key="tabControlStyle" TargetType="{x:Type TabControl}">
            <Setter Property="SnapsToDevicePixels" Value="True"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabControl}">
                        <Grid KeyboardNavigation.TabNavigation="Local">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="*"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>

                            <!--برای نمایشِ قسمتِ Header یا همون Tab Item مربوط به کنترل TabControl ، بجای
                            استفاده از TabPanel ، میتونیم از ItemPresenter هم استفاده کنیم
                            اما TabPanel برای مدیریت آیتم یا همون هِدِر های TabControl بهتر هست-->
                            <!--<ItemsPresenter x:Name="ItemsPresenter" Grid.Row="0"/>-->
                            <!--تعیینِ پروپرتیِ IsItemsHost برای اینکه آیتم ها که در اینجا همون هِدِر ها یا همون TabItem ها هستن ، نمایش داده بشن یا نه ، ضروری هست-->
                            <Border Name="tabItemsBorder" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3" Grid.RowSpan="1" Background="{TemplateBinding Background}" BorderThickness="1" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="2">
                                <TabPanel Name="tabItemsPanel" Background="Transparent" IsItemsHost="True" Margin="1" Panel.ZIndex="1" KeyboardNavigation.TabIndex="1"/>
                            </Border>

                            <Border Name="tabContainerBorder" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="3" Grid.RowSpan="1" KeyboardNavigation.TabNavigation="Local" KeyboardNavigation.DirectionalNavigation="Contained" KeyboardNavigation.TabIndex="2" BorderThickness="1" BorderBrush="Green" Background="#FF9E9E9E">
                                <ScrollViewer Name="tabContainerScrollViewer" CanContentScroll="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" >
                                    <ContentPresenter Name="PART_SelectedContentHost" Margin="0" ContentSource="SelectedContent"/>
                                </ScrollViewer>
                            </Border>
                        </Grid>

                        <ControlTemplate.Triggers>
                            <Trigger Property="TabStripPlacement" Value="Right">
                                <Setter TargetName="tabItemsBorder" Property="Grid.Column" Value="2"/>
                                <Setter TargetName="tabItemsBorder" Property="Grid.Row" Value="0"/>
                                <Setter TargetName="tabItemsBorder" Property="Grid.ColumnSpan" Value="1"/>
                                <Setter TargetName="tabItemsBorder" Property="Grid.RowSpan" Value="3"/>

                                <Setter TargetName="tabContainerBorder" Property="Grid.Column" Value="0"/>
                                <Setter TargetName="tabContainerBorder" Property="Grid.Row" Value="0"/>
                                <Setter TargetName="tabContainerBorder" Property="Grid.ColumnSpan" Value="2"/>
                                <Setter TargetName="tabContainerBorder" Property="Grid.RowSpan" Value="3"/>
                            </Trigger>
                            <Trigger Property="TabStripPlacement" Value="Left">
                                <Setter TargetName="tabItemsBorder" Property="Grid.Column" Value="0"/>
                                <Setter TargetName="tabItemsBorder" Property="Grid.Row" Value="0"/>
                                <Setter TargetName="tabItemsBorder" Property="Grid.ColumnSpan" Value="1"/>
                                <Setter TargetName="tabItemsBorder" Property="Grid.RowSpan" Value="3"/>

                                <Setter TargetName="tabContainerBorder" Property="Grid.Column" Value="1"/>
                                <Setter TargetName="tabContainerBorder" Property="Grid.Row" Value="0"/>
                                <Setter TargetName="tabContainerBorder" Property="Grid.ColumnSpan" Value="2"/>
                                <Setter TargetName="tabContainerBorder" Property="Grid.RowSpan" Value="3"/>
                            </Trigger>
                            <Trigger Property="TabStripPlacement" Value="Bottom">
                                <Setter TargetName="tabItemsBorder" Property="Grid.Column" Value="0"/>
                                <Setter TargetName="tabItemsBorder" Property="Grid.Row" Value="2"/>
                                <Setter TargetName="tabItemsBorder" Property="Grid.ColumnSpan" Value="3"/>
                                <Setter TargetName="tabItemsBorder" Property="Grid.RowSpan" Value="1"/>

                                <Setter TargetName="tabContainerBorder" Property="Grid.Column" Value="0"/>
                                <Setter TargetName="tabContainerBorder" Property="Grid.Row" Value="0"/>
                                <Setter TargetName="tabContainerBorder" Property="Grid.ColumnSpan" Value="3"/>
                                <Setter TargetName="tabContainerBorder" Property="Grid.RowSpan" Value="2"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>




        <Style x:Key="tabItemStyle" TargetType="{x:Type TabItem}">
            <Setter Property="MinWidth" Value="60"/>
            <Setter Property="MinHeight" Value="23"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="{StaticResource tabItem_DefaultSelectedBorderBrush}"/>
            <Setter Property="Foreground" Value="{StaticResource tabItem_DefaultForegroundBrush}"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabItem}">
                        <Border Name="tabItemBorder" Background="{TemplateBinding Background}" BorderThickness="1" BorderBrush="Transparent">
                            <ContentPresenter TextBlock.Foreground="{TemplateBinding Foreground}" Name="ContentSite" ContentSource="Header" RecognizesAccessKey="True" HorizontalAlignment="Center" VerticalAlignment="Center" />
                        </Border>

                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter TargetName="tabItemBorder" Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BorderBrush}"/>
                            </Trigger>
                            <Trigger Property="IsFocused" Value="True">
                                <Setter TargetName="tabItemBorder" Property="Background" Value="Red"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
اگه بخوایم وقتی اون تریگری که در TabItem هست ، یعنی وقتی که تریگرِ زیر :

XML:
<Trigger Property="IsFocused" Value="True">
اجرا شد ، بجای اون setter اش ، این جوری که در زیر میگم ، setter را انجام بده :
که بره پروپرتیِ Foreground ئه TabControl مربوطه را بگیره و توی پروپرتیِ BorderBrush ئه المنت tabItemsBorder سِت کنه ، بهترین کدی که براش میشه نوشت ، چیه؟

البته نمیدونم این سئوال را قبلا پرسیدم یا نه .
یعنی اون قضیه ی DataTrigger را که گفته بودین ، حالا این دقیقا همون ماجراست اما برای Setter میخوام binding کنه (که میدونید اجازه ی binding ئه پروپرتی Property ئه Setter را نمیده) .

از فلگ استفاده کنیم یا راه دیگه ای هم هست؟
تشکر استاد :rose:
 

the_king

مدیرکل انجمن
سلام استاد .
خیلی ممنون استاد .
در رویداد GotFocus ئه DoubleUpDown (که تمپلیت را بکار بردم)، با پروپرتیِ Keyboard.FocusedElement ، المنت ای که فوکوس میشه را گرفتم (کد تمپلیت را در زیر پیوست میکنم) .
وقتی روی این کنترلِ DoubleUpDown ، فوکوس میکنم ، در 3 المنت از تمپلیت ، فوکوس میکنه (که رفع ماجرای این قضیه که فقط روی یک المنت در تمپلیت فوکوس کنه هم انگار داستانه) .

اولین بار با فوکوس روی این کنترل DoubleUpDown ، روی المنتِ PART_TextBox فوکوس میکنه . وقتی روی این المنت فوکوس کنه ، با فشردن کلیدهای فِلِش بالا و پایین در کیبرد (Arrow up _ down) ، هیچ اتفاقی نمیافته (یعنی با فشردن کلید فلش بالا یا پایین کیبرد ، عددِ درونِ همین textbox ، کم یا زیاد نمیشه) .

وقتی دوباره کلید Tab کیبرد را میزنم ، فوکوس روی المنتِ PART_IncreaseButton که در تمپلیت وجود داره ، میره . حالا با فوکوس بودن روی این المنت ، اگه کلیدهای فِلِش بالا و پایین در کیبرد را فشار بدم ، عدد در اون textbox ، کم یا زیاد میشه و کار میکنه .

باز دوباره کلید tab را بزنم ، فوکوس روی المنتِ PART_DecreaseButton که در تمپلیت وجود داره ، میره . قضیه ی این هم مثل قضیه ی فوکوس روی PART_IncreaseButton هست (یعنی با فشردن فلش ها ، اعداد تغییر میکنن و کار میکنه) .

خوب حالا اینجا چند تا مشکل وجود داره :
اینو بگم که خوب میشه Focusable ئه یکی از PART_DecreaseButton یا PART_IncreaseButton را False کرد تا علی الحساب ، فوکوس شدن یه المنت ، کمتر بشه اما :
1) باز هم مشکل اینه که در این تمپلیت ، 2 تا المنت فوکوس میشن . یکی PART_TextBox و یکی دیگه هم PART_IncreaseButton (فرضا Focusable ئه PART_DecreaseButton را False کنم) .

2) اگه Focusable ئه PART_TextBox را False کنم ، بخش TextBox قابلیت فوکوس نخواهد داشت و نمیشه کاربر عدد مورد نظرش را وارد کنه (عملا Read Only میشه) . پس Focusable ئه PART_TextBox قطعا باید True بمونه .

3) اگه Focusable ئه PART_IncreaseButton را False کنم ، دیگه اون قضیه ی کیبرد (با فشردن فلش کیبرد ، اعداد تغییر میکردن) ، دیگه کار نمیکنه .

حالا سئوال اینجاست که چی کار کنم که هم این قضیه ی کیبرد کار کنه (تا اینجا انگار راهش اینه که فوکوس روی PART_IncreaseButton باشه) و هم توی کل تمپلیت ، فوکوس فقط روی یک المنت اش اتفاق بیافته (جوری که کاربر بتونه عدد رو توی TextBox وارد کنه) ؟

چون ممکنه بقیه ، داخل این پست جا نگیره ، ادامه را در پست بعدی میگم .
طومار شد ، ببخشید . تشکر :rose:
مشکل رو خودتون ایجاد کرده اید، بجای اینکه بر اساس Style کنترل پیش برید، به میل خودتون یک Style ناسازگار طراحی کرده اید که یک TextBox عادی داخلش داره و برای کلید های مکان نما هیچ برنامه ای نداره. در Style پیشفرض کنترل ئه ببینید نوع المنتی که برای PART_TextBox استفاده کرده چیه؟ از نوع TextBox ساده است؟
 

the_king

مدیرکل انجمن
این قضیه را متوجه شدم .
اما یه سئوال دیگه اینکه الان در کد زیر :

XML:
        <Style x:Key="tabControlStyle" TargetType="{x:Type TabControl}">
            <Setter Property="SnapsToDevicePixels" Value="True"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabControl}">
                        <Grid KeyboardNavigation.TabNavigation="Local">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="*"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>

                            <!--برای نمایشِ قسمتِ Header یا همون Tab Item مربوط به کنترل TabControl ، بجای
                            استفاده از TabPanel ، میتونیم از ItemPresenter هم استفاده کنیم
                            اما TabPanel برای مدیریت آیتم یا همون هِدِر های TabControl بهتر هست-->
                            <!--<ItemsPresenter x:Name="ItemsPresenter" Grid.Row="0"/>-->
                            <!--تعیینِ پروپرتیِ IsItemsHost برای اینکه آیتم ها که در اینجا همون هِدِر ها یا همون TabItem ها هستن ، نمایش داده بشن یا نه ، ضروری هست-->
                            <Border Name="tabItemsBorder" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3" Grid.RowSpan="1" Background="{TemplateBinding Background}" BorderThickness="1" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="2">
                                <TabPanel Name="tabItemsPanel" Background="Transparent" IsItemsHost="True" Margin="1" Panel.ZIndex="1" KeyboardNavigation.TabIndex="1"/>
                            </Border>

                            <Border Name="tabContainerBorder" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="3" Grid.RowSpan="1" KeyboardNavigation.TabNavigation="Local" KeyboardNavigation.DirectionalNavigation="Contained" KeyboardNavigation.TabIndex="2" BorderThickness="1" BorderBrush="Green" Background="#FF9E9E9E">
                                <ScrollViewer Name="tabContainerScrollViewer" CanContentScroll="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" >
                                    <ContentPresenter Name="PART_SelectedContentHost" Margin="0" ContentSource="SelectedContent"/>
                                </ScrollViewer>
                            </Border>
                        </Grid>

                        <ControlTemplate.Triggers>
                            <Trigger Property="TabStripPlacement" Value="Right">
                                <Setter TargetName="tabItemsBorder" Property="Grid.Column" Value="2"/>
                                <Setter TargetName="tabItemsBorder" Property="Grid.Row" Value="0"/>
                                <Setter TargetName="tabItemsBorder" Property="Grid.ColumnSpan" Value="1"/>
                                <Setter TargetName="tabItemsBorder" Property="Grid.RowSpan" Value="3"/>

                                <Setter TargetName="tabContainerBorder" Property="Grid.Column" Value="0"/>
                                <Setter TargetName="tabContainerBorder" Property="Grid.Row" Value="0"/>
                                <Setter TargetName="tabContainerBorder" Property="Grid.ColumnSpan" Value="2"/>
                                <Setter TargetName="tabContainerBorder" Property="Grid.RowSpan" Value="3"/>
                            </Trigger>
                            <Trigger Property="TabStripPlacement" Value="Left">
                                <Setter TargetName="tabItemsBorder" Property="Grid.Column" Value="0"/>
                                <Setter TargetName="tabItemsBorder" Property="Grid.Row" Value="0"/>
                                <Setter TargetName="tabItemsBorder" Property="Grid.ColumnSpan" Value="1"/>
                                <Setter TargetName="tabItemsBorder" Property="Grid.RowSpan" Value="3"/>

                                <Setter TargetName="tabContainerBorder" Property="Grid.Column" Value="1"/>
                                <Setter TargetName="tabContainerBorder" Property="Grid.Row" Value="0"/>
                                <Setter TargetName="tabContainerBorder" Property="Grid.ColumnSpan" Value="2"/>
                                <Setter TargetName="tabContainerBorder" Property="Grid.RowSpan" Value="3"/>
                            </Trigger>
                            <Trigger Property="TabStripPlacement" Value="Bottom">
                                <Setter TargetName="tabItemsBorder" Property="Grid.Column" Value="0"/>
                                <Setter TargetName="tabItemsBorder" Property="Grid.Row" Value="2"/>
                                <Setter TargetName="tabItemsBorder" Property="Grid.ColumnSpan" Value="3"/>
                                <Setter TargetName="tabItemsBorder" Property="Grid.RowSpan" Value="1"/>

                                <Setter TargetName="tabContainerBorder" Property="Grid.Column" Value="0"/>
                                <Setter TargetName="tabContainerBorder" Property="Grid.Row" Value="0"/>
                                <Setter TargetName="tabContainerBorder" Property="Grid.ColumnSpan" Value="3"/>
                                <Setter TargetName="tabContainerBorder" Property="Grid.RowSpan" Value="2"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>




        <Style x:Key="tabItemStyle" TargetType="{x:Type TabItem}">
            <Setter Property="MinWidth" Value="60"/>
            <Setter Property="MinHeight" Value="23"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="{StaticResource tabItem_DefaultSelectedBorderBrush}"/>
            <Setter Property="Foreground" Value="{StaticResource tabItem_DefaultForegroundBrush}"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabItem}">
                        <Border Name="tabItemBorder" Background="{TemplateBinding Background}" BorderThickness="1" BorderBrush="Transparent">
                            <ContentPresenter TextBlock.Foreground="{TemplateBinding Foreground}" Name="ContentSite" ContentSource="Header" RecognizesAccessKey="True" HorizontalAlignment="Center" VerticalAlignment="Center" />
                        </Border>

                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter TargetName="tabItemBorder" Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BorderBrush}"/>
                            </Trigger>
                            <Trigger Property="IsFocused" Value="True">
                                <Setter TargetName="tabItemBorder" Property="Background" Value="Red"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
اگه بخوایم وقتی اون تریگری که در TabItem هست ، یعنی وقتی که تریگرِ زیر :

XML:
<Trigger Property="IsFocused" Value="True">
اجرا شد ، بجای اون setter اش ، این جوری که در زیر میگم ، setter را انجام بده :
که بره پروپرتیِ Foreground ئه TabControl مربوطه را بگیره و توی پروپرتیِ BorderBrush ئه المنت tabItemsBorder سِت کنه ، بهترین کدی که براش میشه نوشت ، چیه؟

البته نمیدونم این سئوال را قبلا پرسیدم یا نه .
یعنی اون قضیه ی DataTrigger را که گفته بودین ، حالا این دقیقا همون ماجراست اما برای Setter میخوام binding کنه (که میدونید اجازه ی binding ئه پروپرتی Property ئه Setter را نمیده) .

از فلگ استفاده کنیم یا راه دیگه ای هم هست؟
تشکر استاد :rose:
بهترین کد یعنی چی؟ بهترین کد تعریف مشخصی داره؟
XML:
<Trigger Property="IsFocused" Value="True">
    <Setter TargetName="tabItemBorder" Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource AncestorType=TabControl}, Path=Foreground}"/>
</Trigger>
 

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

بالا