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

the_king

مدیرکل انجمن
خیلی ممنون استاد .
فرض کنید که (در کد پست قبل) ، اون CheckBox (یا هر کنترل دیگه ای) ، یه Panel داشته باشه که توی اون پنل ، فرضا صد ها کنترل و ده ها Button وجود داشته باشه .
در وجهه ی برنامه ریخت و پاش ایجاد میشه که برای اون ده ها Button ، رویدادِ کلیک ایجاد کنیم و توش e.Handled = true را بنویسیم بخاطر این قضیه .
تازه رویدادهای دیگه ی Routed Event هم هستند که بخوایم این کار را کنیم .

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

اصلا یکی از اهداف اینکه routed event ها اومدن ، این هست که اگه خواستیم یه رویداد مشترک تعریف کنیم ، نخوایم ، هندلرِ اون رویداد واحد را هر بار به هر کنترل متصل کنیم . درست میگم؟

تشکر استاد .
سوال تون با راهکار تون جور در نمیاد، "اگه بخوایم فقط زمانی که اون CheckBox مون براش رویداد Click اتفاق افتاد ، فقط در این صورت ، این رویدادِ CheckBoxRoutedEvent_Click اجرا بشه" فرق می کنه با اینکه در CheckBoxRoutedEvent_Click کار خاصی رو فقط زمانی که کلیک روی اون CheckBox بود انجام بدهید. من به سوال شما پاسخ دادم. این راهکاری که خودتون ارائه کردید باعث نمیشه که CheckBoxRoutedEvent_Click فقط زمانی که کلیک روی اون CheckBox بود اجرا بشه.
 

SajjadKhati

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

راستی استاد یه سئوال . نمیدونم این سئوال (شاید ساده) ، چرا تا حالا برام مطرح نشد!
الان در کدِ همون پروژه که در زیر میذارم :

XML:
        <ListView Name="ListView1" Margin="0, 240, 0, 0" ItemsSource="{Binding Path=StudentsForListView}">
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Width="200" Header="{Binding StudentsForListView/FirstName}" DisplayMemberBinding="{Binding FirstName}" />
                        <GridViewColumn Width="200"  Header="Last Name" DisplayMemberBinding="{Binding LastName}"/>
                    </GridView.Columns>
                </GridView>
            </ListView.View>

            <ListView.ItemContainerStyle>
                <Style TargetType="{x:Type ListViewItem}">
                    <EventSetter Event="MouseEnter" Handler="ListViewItem_MouseEnter"/>
                </Style>
            </ListView.ItemContainerStyle>
        </ListView>

در کد بالا و در خط :

XML:
<GridViewColumn Width="200" Header="{Binding StudentsForListView/FirstName}" DisplayMemberBinding="{Binding FirstName}" />

خوب DataContext ئه والدش که از نوع StudentViewModel هست ، بنابراین Source ئه ListView هم همون شیِ StudentViewModel هست (که میدونیم) .
بنابراین Source ئه Binding ای که حتی در پروپرتیِ DisplayMemberBinding (در شی GridViewColumn) بکار بردیم هم همون شیِ StudentViewModel هست دیگه . درسته؟

حالا در Path ئه Binding (برای پروپرتیِ DisplayMemberBinding) ، یه پروپرتی ای را دادیم (پروپرتیِ FirstName را دادیم) که درون Source ئه اون Binding (که StudentViewModel هست) ، وجود نداره ، بنابراین این از کجا میدونه که داخلِ کدوم کالکشنی که در کلاس StudentViewModel وجود داره باید بگرده؟
درون کلاس StudentViewModel ، فرضا ممکنه 10 تا کالکشن وجود داشته باشه .
آیا درون همه ی این 10 تا کالکشن میگرده تا ببینه توی کدوم یک از پروپرتی های عضو CurrentItem ئه CollectionView (ی مربوط به کالکشن) ، پروپرتیِ FirstName وجود داره؟
متوجه ی منظورم شدید؟

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

بعد اینکه الان در Binding ای که در پروپرتیِ Header انجام شد ، همه چیز به ترتیب و مرتب انجام شد .
یعنی در Binding ئه پروپرتیِ Header ، مقدار Source اش که شیِ StudentViewModel هست . در Path اش هم گفتیم که درون این شیِ StudentViewModel ، یه کالکشن ای بنام StudentsForListView وجود داره و برو به CurrentItem (ئه CollectionView ی مربوط به این کالکشن) و مقدارِ پروپرتیِ FirstName اش را Binding کن .
از نظر من ، این درسته . چون دقیقا میدونه توی کدوم کالکشن باید بگرده .

اما نکته ی جالب اینجاست با اونکه این کد درست عمل میکنه ، اما اگه Binding هایی را که برای پروپرتی های Header و پروپرتیِ DisplayMemberBinding (در GridViewColumn) نوشتیم را عوض کنیم ، یعنی مثلا بصورت کد زیر بنویسیم :

XML:
<GridViewColumn Width="200" Header="{Binding FirstName}" DisplayMemberBinding="{Binding StudentsForListView/FirstName}" />

دیگه هیچ کدوم از Binding های این دو پروپرتی ، کار نمیکنن . چرا؟!
به نظر میرسه که الگوی نوشتن Binding برای پروپرتیِ DisplayMemberBinding هست که فرق داره . درست میگم؟
اگه اشتباه میکنم ، یا به هر صورت ، جریان این قضیه چجوری هه؟

چون پروپرتیِ DisplayMemberBinding ، یه DependencyProperty نیست ، نمیتونم با متد BindingOperations.GetBinding ، Binding ای که در xaml دادم را در سی شارپ بگیرم . شما روشی میشناسید؟

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

the_king

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

راستی استاد یه سئوال . نمیدونم این سئوال (شاید ساده) ، چرا تا حالا برام مطرح نشد!
الان در کدِ همون پروژه که در زیر میذارم :

XML:
        <ListView Name="ListView1" Margin="0, 240, 0, 0" ItemsSource="{Binding Path=StudentsForListView}">
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Width="200" Header="{Binding StudentsForListView/FirstName}" DisplayMemberBinding="{Binding FirstName}" />
                        <GridViewColumn Width="200"  Header="Last Name" DisplayMemberBinding="{Binding LastName}"/>
                    </GridView.Columns>
                </GridView>
            </ListView.View>

            <ListView.ItemContainerStyle>
                <Style TargetType="{x:Type ListViewItem}">
                    <EventSetter Event="MouseEnter" Handler="ListViewItem_MouseEnter"/>
                </Style>
            </ListView.ItemContainerStyle>
        </ListView>

در کد بالا و در خط :

XML:
<GridViewColumn Width="200" Header="{Binding StudentsForListView/FirstName}" DisplayMemberBinding="{Binding FirstName}" />

خوب DataContext ئه والدش که از نوع StudentViewModel هست ، بنابراین Source ئه ListView هم همون شیِ StudentViewModel هست (که میدونیم) .
بنابراین Source ئه Binding ای که حتی در پروپرتیِ DisplayMemberBinding (در شی GridViewColumn) بکار بردیم هم همون شیِ StudentViewModel هست دیگه . درسته؟

حالا در Path ئه Binding (برای پروپرتیِ DisplayMemberBinding) ، یه پروپرتی ای را دادیم (پروپرتیِ FirstName را دادیم) که درون Source ئه اون Binding (که StudentViewModel هست) ، وجود نداره ، بنابراین این از کجا میدونه که داخلِ کدوم کالکشنی که در کلاس StudentViewModel وجود داره باید بگرده؟
درون کلاس StudentViewModel ، فرضا ممکنه 10 تا کالکشن وجود داشته باشه .
اون ItemsSource منبعی است که قراره Item های داخلش نمایش داده بشه، Item ها رو کی تعیین می کنه؟ خود کلاس StudentViewModel، نه ListView.
اون ItemsSource که نمیاد برای پیدا کردن اعضاء ساختار داخل StudentViewModel رو بررسی کنه، این Enumerator خود StudentViewModel ئه که تصمیم میگیره چه اعضاء ای رو برگردونه.
اگر <List<string اعضاء string بر می گردونه بخاطر اون IEnumerable و <IEnumerable<string اش هست، نه چیز دیگری.
اینکه در StudentViewModel چه ساختار هایی هست حداقل در این مورد اهمیتی نداره، مهم اینه که اون IEnumerable ای که برای کلاس پیاده سازی شده با Enumerator اش چه اعضاء ای رو برگردونه، اگر اعضاء ای که بر می گردونه FirstName داشته باشند استفاده میشه.
آیا درون همه ی این 10 تا کالکشن میگرده تا ببینه توی کدوم یک از پروپرتی های عضو CurrentItem ئه CollectionView (ی مربوط به کالکشن) ، پروپرتیِ FirstName وجود داره؟
نه. یک کلاس فقط یک متد ()IEnumerator IEnumerable.GetEnumerator میتونه داشته باشه، نه بیشتر. چند حالتی وجود نداره که ابهام پیش بیاد.
اما نکته ی جالب اینجاست با اونکه این کد درست عمل میکنه ، اما اگه Binding هایی را که برای پروپرتی های Header و پروپرتیِ DisplayMemberBinding (در GridViewColumn) نوشتیم را عوض کنیم ، یعنی مثلا بصورت کد زیر بنویسیم :

XML:
<GridViewColumn Width="200" Header="{Binding FirstName}" DisplayMemberBinding="{Binding StudentsForListView/FirstName}" />

دیگه هیچ کدوم از Binding های این دو پروپرتی ، کار نمیکنن . چرا؟!
چون Header عنوان ئه، عنوان الزاما ربطی به یک عضو خاص نداره، داخل لیست نیست، بیرون لیست ئه.
اما DisplayMemberBinding برای اون عضو ای است که در سطر فعلی داخل لیست نمایش داده بشه، فرضا اگر سه تا عضو در لیست هست، سه مقدار از DisplayMemberBinding دریافت میشه. در داده های اون عضو StudentsForListView/FirstName رو پیدا نمی کنه، چون مشخصه ای به نام StudentsForListView نداره.
به نظر میرسه که الگوی نوشتن Binding برای پروپرتیِ DisplayMemberBinding هست که فرق داره . درست میگم؟
الگو اش فرق می کنه چون منبع اش اعضاء ItemsSource ئه، نه خود ItemsSource.
 

SajjadKhati

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

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

الان خلاصه ی کلام تون ، همین جمله میشه؟
یعنی منبعِ پروپرتیِ DisplayMemberBinding (در کد پست قبلی ام) ، عضوِ CurrentPath (ئه CollectionView ی مربوط به کالکشن مون) ای هست که در شیِ Binding که درون پروپرتیِ ItemsSource اش مشخص کرده بودیم؟
در کل ، منبعِ DisplayMemberBinding ، عضو Path در Binding ئه پروپرتیِ ItemsSource ئه والدش میشه؟

چون من مقدار این پروپرتی را گرفتم :

XML:
<GridViewColumn x:Name="GVColunm" Width="200" Header="FirstName" DisplayMemberBinding="{Binding FirstName}" />

و

C#:
Binding binding = this.GVColunm.DisplayMemberBinding as Binding;

اما پروپرتیِ Source ئه این Binding (ئه DisplayMemberBinding) را null زده بود .
مگه DataContext ای که مشخص کرده بودیم ، به عنوان Source ئه Binding های تمام والدهاش بکار نمیره؟
کلا از این شیِ Binding ای که در کد بالا هست ، از کجا متوجه بشیم که Binding Source Object اش چیه؟
یه مقدار گیج کننده هست.

تشکر استاد .
 

the_king

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

الان خلاصه ی کلام تون ، همین جمله میشه؟
یعنی منبعِ پروپرتیِ DisplayMemberBinding (در کد پست قبلی ام) ، عضوِ CurrentPath (ئه CollectionView ی مربوط به کالکشن مون) ای هست که در شیِ Binding که درون پروپرتیِ ItemsSource اش مشخص کرده بودیم؟
در کل ، منبعِ DisplayMemberBinding ، عضو Path در Binding ئه پروپرتیِ ItemsSource ئه والدش میشه؟
CurrentPath دیگه چیه؟ منبع DisplayMemberBinding اعضاء مجموعه ای است که ItemsSource مشخص کرده. اینکه کنترل چی رو استفاده کنه و چی رو نمایش بده Binding مشخص نمی کنه، Binding فقط رابط ئه، فرضا روال داخل OnColumnPropertyChanged در GridViewRowPresenter میاد با یکسری کد ها تصمیم می گیره که اگر در Binding ئه DisplayMemberBinding فلان حالت بود فلان چیز رو نشون بده و فلان کار رو انجام بده و اگر حالت دیگری بود رفتار دیگری داره.
اینها رفتار فلان کنترل خاصی فرضا GridView ئه، حکم نیست که هر جا Binding بود پس باید همون ItemsSource والد اش رو بکار ببره یا اعضاء اش یا شرایط دیگری. Binding رابط ئه، هر کنترلی میتونه در مورد اینکه از داده های رابط چطور استفاده کنه تصمیم بگیره.
چون من مقدار این پروپرتی را گرفتم :

XML:
<GridViewColumn x:Name="GVColunm" Width="200" Header="FirstName" DisplayMemberBinding="{Binding FirstName}" />

و

C#:
Binding binding = this.GVColunm.DisplayMemberBinding as Binding;

اما پروپرتیِ Source ئه این Binding (ئه DisplayMemberBinding) را null زده بود .
مگه DataContext ای که مشخص کرده بودیم ، به عنوان Source ئه Binding های تمام والدهاش بکار نمیره؟
اینجا DataContext ای ندارید، DataContext مشخصه کدوم کلاس بود؟ FrameworkElement ها، مثلا ListView و ListViewItem. درسته؟
GridView و GridViewColumn مگه FrameworkElement هستند که DataContext داشته باشند؟
کلا از این شیِ Binding ای که در کد بالا هست ، از کجا متوجه بشیم که Binding Source Object اش چیه؟
یه مقدار گیج کننده هست.
گیج کننده نیست، توضیحات کنترل رو می خوانید تا ببینید اون مشخصه تعیین کننده چیه و Binding اون مشخصه قراره منبع داده چی باشه.
وقتی بدونید منبع داده برای چی قراره استفاده بشه متوجه می شوید که فرضا باید اطلاعات خود مجموعه باشه یا اطلاعات یک عضو مجموعه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
CurrentPath دیگه چیه؟

خیلی ممنون استاد .
منظورم CurrentItem (ئه CollectionView) بود . کلا اشتباه گفتم .


اینکه کنترل چی رو استفاده کنه و چی رو نمایش بده Binding مشخص نمی کنه، Binding فقط رابط ئه،

فرضا روال داخل OnColumnPropertyChanged در GridViewRowPresenter میاد با یکسری کد ها تصمیم می گیره که اگر در Binding ئه DisplayMemberBinding فلان حالت بود فلان چیز رو نشون بده و فلان کار رو انجام بده و اگر حالت دیگری بود رفتار دیگری داره.
اینها رفتار فلان کنترل خاصی فرضا GridView ئه، حکم نیست که هر جا Binding بود پس باید همون ItemsSource والد اش رو بکار ببره یا اعضاء اش یا شرایط دیگری. Binding رابط ئه، هر کنترلی میتونه در مورد اینکه از داده های رابط چطور استفاده کنه تصمیم بگیره.

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


منبع DisplayMemberBinding اعضاء مجموعه ای است که ItemsSource مشخص کرده.

پس نکته ی مهم دیگه اینه که منبعِ Binding در پروپرتیِ DisplayMemberBinding ، اعضای کالکشن ای هست که در پروپرتیِ Path (در Binding) ای که برای پروپرتیِ ItemsSource مشخص کرده بودیم ، هست .
یا اگه برای ItemsSource ، عمل Binding انجام ندادیم ، کلا اعضای کالکشنِ این پروپرتیِ ، به عنوان منبعِ DisplayMemberBinding مشخص میشن؟
درست میگم؟

در واقع ، شیِ Binding ای که برای پروپرتیِ DisplayMemberBinding مشخص کرده بودیم ، تعیین نمیکنه که Source یا DataContext اش چی هست . در واقع از Source یا DataContext ای که قبلا تعیین کرده بودیم ، به عنوان منبع طبعیت و پیروی نمیکنه .
بلکه خودِ پروپرتیِ DisplayMemberBinding ، منبع اش را از اعضای ItemsSource میگیره.
پس انتخاب منبع ، میتونه دست ما نباشه و خودِ پروپرتی در کنترلی (در واقع همون Target Property) ، بیاد و خودش ، منبعِ خودش را انتخاب کنه .
درست میگم؟

اینجا DataContext ای ندارید، DataContext مشخصه کدوم کلاس بود؟ FrameworkElement ها، مثلا ListView و ListViewItem. درسته؟
GridView و GridViewColumn مگه FrameworkElement هستند که DataContext داشته باشند؟

DataContext ، قبلابرای Window در همون پروژه ی قبلی تعریف شده بود .
گفتم که این کد را از اون پروژه گرفتم (پروژه را قبلا آپلود کردم) .

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

توی توضیحاتِ پروپرتیِ GridViewColumn.DisplayMemberBinding دیدم .
ای کاش بصورت صریح ، مثلا اشاره میکرد که فرضا منبعِ پروپرتیِ DisplayMemberBinding ، اعضای کالکشنِ ItemsSource ئه کنترلِ مربوطه هست .
چون اگه این طور نباشه که ما از کجا بدونیم که منبعش را این پروپرتی داره تغییر میده و اونی نیست که ما در Binding یا در DataContext ئه والدش مشخص کرده بودیم .

در توضیحات DisplayMemberBinding نوشته که یک نوعِ داده را از یه Data Source ، به یه ستون ربط میده .
حرفی از این نزد که منبعِ Binding مون را خودش مدیریت میکنه و منبعِ اون هم ، اعضای ItemsSource (یا اعضای هر Data Source ئه دیگری در اون کنترلِ مربوطه) هستن .

تشکر استاد .
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
منظورم CurrentItem (ئه CollectionView) بود . کلا اشتباه گفتم .






آها .
یعنی Binding نیست که تعیین میکنه که منبعِ همون Binding ای که مشخص کردیم ، چی باشه؟
اتفاقا Binding منبع رو مشخص می کنه اما اینکه کنترل از منبع به چه شکلی استفاده کنه، خودش رو بکار ببره، از اعضاء داخلش استفاده کنه یا کلا اینکه با منبع چطور رفتار کنه رو Binding تعیین نمی کنه.
بلکه این پروپرتی های خودِ کنترل و همچنین خودِ کنترل هست که تعیین میکنه که منبعِ Binding ای که ما مشخص کردیم را از کجا (و فرضا ، از کدوم کنترل) بگیره؟
بله.
پس نکته ی مهم دیگه اینه که منبعِ Binding در پروپرتیِ DisplayMemberBinding ، اعضای کالکشن ای هست که در پروپرتیِ Path (در Binding) ای که برای پروپرتیِ ItemsSource مشخص کرده بودیم ، هست .
بله.
یا اگه برای ItemsSource ، عمل Binding انجام ندادیم ، کلا اعضای کالکشنِ این پروپرتیِ ، به عنوان منبعِ DisplayMemberBinding مشخص میشن؟
درست میگم؟
فرقی نمی کنه، Binding صرفا برای ارتباط منبع با مشخصه است، چه با Binding و چه بدون Binding منبع رو برای مشخصه تعیین می کنید.
در واقع ، شیِ Binding ای که برای پروپرتیِ DisplayMemberBinding مشخص کرده بودیم ، تعیین نمیکنه که Source یا DataContext اش چی هست . در واقع از Source یا DataContext ای که قبلا تعیین کرده بودیم ، به عنوان منبع طبعیت و پیروی نمیکنه .
کاری با DataContext نداره چون کنترل اش کاری با DataContext نداره.
Source رو طراح Binding تعیین می کنه، اگر طراح بخواد Source رو تعیین کنه می کنه، Binding رو خودش داره می نویسه. من یادم نمیاد قاعده ای برای Source تعیین کرده باشیم.
XML:
        <ListView>
            <ListView.ItemsSource>
                <x:Array Type="Color">
                    <Color>Yellow</Color>
                    <Color>Magenta</Color>
                </x:Array>
            </ListView.ItemsSource>
            <ListView.Resources>
                <Color x:Key="MyColor" R="50" G="100" B="200"/>
            </ListView.Resources>
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Width="150" Header="Red" DisplayMemberBinding="{Binding Source={StaticResource MyColor}, Path=R}"/>
                        <GridViewColumn Width="150" Header="Green" DisplayMemberBinding="{Binding Source={StaticResource MyColor}, Path=G}"/>
                        <GridViewColumn Width="150" Header="Blue" DisplayMemberBinding="{Binding Source={StaticResource MyColor}, Path=B}"/>
                    </GridView.Columns>
                </GridView>
            </ListView.View>
        </ListView>

بلکه خودِ پروپرتیِ DisplayMemberBinding ، منبع اش را از اعضای ItemsSource میگیره.
پس انتخاب منبع ، میتونه دست ما نباشه و خودِ پروپرتی در کنترلی (در واقع همون Target Property) ، بیاد و خودش ، منبعِ خودش را انتخاب کنه .
درست میگم؟
چرا دست ما نیست؟ اشتباه ئه. اگر قرار بود منبع رو خودمون تعیین نکنیم که وجود مشخصه لازم نبود.
توی توضیحاتِ پروپرتیِ GridViewColumn.DisplayMemberBinding دیدم .
ای کاش بصورت صریح ، مثلا اشاره میکرد که فرضا منبعِ پروپرتیِ DisplayMemberBinding ، اعضای کالکشنِ ItemsSource ئه کنترلِ مربوطه هست .
شما می توانستید تصور کنید که DisplayMemberBinding به چیز دیگری مربوط باشه؟ یک توصیف منطقی دیگری می توانید پیدا کنید که اینطور نباشه؟
GridView برای توصیف ظاهر جدول داخل ListView ئه، اینکه شرح کلی GridView ئه، پس بدیهی ئه که منبع اش محتویات ListView باشه.
جدول هم یکسری ستون ئه، فرضا سه ستون.
که تعداد و عنوان ستون ها معمولا ربطی به تعداد اعضاء اون منبع داده ListView نداره، یعنی به تعداد اعضاء ربطی نداره، برای همین Header معمولا یک مقدار مستقل از اعضاء ئه که برای همه سطر ها مشترک ئه. مثلا FirstName ، مقدار سطرهای جدول هم که DisplayMemberBinding مشخص می کنه به اعضاء اون منبع داده مربوط ئه، چون فرضا اگر منبع داده پنج تا عضو داره، معمولا پنج تا سطر هم در جدول وجود داره.
GridViewColumn هم برای توصیف ستون های اون جدول ئه، DisplayMemberBinding هم عضوی است که باید به عنوان مقدار ردیف های جدول نمایش داده بشه، مثلا Ali و Hasan پس بدیهی ئه که منبع اش اعضاء منبعی باشه که داخل ListView نمایش داده میشه.
اگر اینطور نبود که ظاهر جدول با محتویات ListView رابطه منطقی نداشت.
چون اگه این طور نباشه که ما از کجا بدونیم که منبعش را این پروپرتی داره تغییر میده و اونی نیست که ما در Binding یا در DataContext ئه والدش مشخص کرده بودیم .

در توضیحات DisplayMemberBinding نوشته که یک نوعِ داده را از یه Data Source ، به یه ستون ربط میده .
حرفی از این نزد که منبعِ Binding مون را خودش مدیریت میکنه و منبعِ اون هم ، اعضای ItemsSource (یا اعضای هر Data Source ئه دیگری در اون کنترلِ مربوطه) هستن .

تشکر استاد .
 

SajjadKhati

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

بله.

بله.

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

کاری با DataContext نداره چون کنترل اش کاری با DataContext نداره.
Source رو طراح Binding تعیین می کنه، اگر طراح بخواد Source رو تعیین کنه می کنه، Binding رو خودش داره می نویسه. من یادم نمیاد قاعده ای برای Source تعیین کرده باشیم.
XML:
        <ListView>
            <ListView.ItemsSource>
                <x:Array Type="Color">
                    <Color>Yellow</Color>
                    <Color>Magenta</Color>
                </x:Array>
            </ListView.ItemsSource>
            <ListView.Resources>
                <Color x:Key="MyColor" R="50" G="100" B="200"/>
            </ListView.Resources>
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Width="150" Header="Red" DisplayMemberBinding="{Binding Source={StaticResource MyColor}, Path=R}"/>
                        <GridViewColumn Width="150" Header="Green" DisplayMemberBinding="{Binding Source={StaticResource MyColor}, Path=G}"/>
                        <GridViewColumn Width="150" Header="Blue" DisplayMemberBinding="{Binding Source={StaticResource MyColor}, Path=B}"/>
                    </GridView.Columns>
                </GridView>
            </ListView.View>
        </ListView>


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

شما می توانستید تصور کنید که DisplayMemberBinding به چیز دیگری مربوط باشه؟ یک توصیف منطقی دیگری می توانید پیدا کنید که اینطور نباشه؟
GridView برای توصیف ظاهر جدول داخل ListView ئه، اینکه شرح کلی GridView ئه، پس بدیهی ئه که منبع اش محتویات ListView باشه.
جدول هم یکسری ستون ئه، فرضا سه ستون.
که تعداد و عنوان ستون ها معمولا ربطی به تعداد اعضاء اون منبع داده ListView نداره، یعنی به تعداد اعضاء ربطی نداره، برای همین Header معمولا یک مقدار مستقل از اعضاء ئه که برای همه سطر ها مشترک ئه. مثلا FirstName ، مقدار سطرهای جدول هم که DisplayMemberBinding مشخص می کنه به اعضاء اون منبع داده مربوط ئه، چون فرضا اگر منبع داده پنج تا عضو داره، معمولا پنج تا سطر هم در جدول وجود داره.
GridViewColumn هم برای توصیف ستون های اون جدول ئه، DisplayMemberBinding هم عضوی است که باید به عنوان مقدار ردیف های جدول نمایش داده بشه، مثلا Ali و Hasan پس بدیهی ئه که منبع اش اعضاء منبعی باشه که داخل ListView نمایش داده میشه.
اگر اینطور نبود که ظاهر جدول با محتویات ListView رابطه منطقی نداشت.

خیلی ممنون استاد .
پس الان اگه برای پروپرتیِ Source ئه Binding (که برای پروپرتیِ DisplayMemberBinding نوشتیم) ، مقداری مشخص کردیم ، که هیچ (در این مثالی که زدید) .

اما نکته ی مهم اینجاست که منبع ئه Binding (که برای پروپرتیِ DisplayMemberBinding نوشتیم) ، برخلاف منبعِ کنترل های عادی که از DataContext ئه کنترل والدشون پیروی میکنن ، منبعِ این پروپرتیِ DisplayMemberBinding ، از DataContext ای که قبلا برای کنترل والدش (مثلا DataContext برای کنترل Window در همون پروژه) تعریف کردیم ، پیروی نمیکنه .

یعنی تعیینِ DataContext در والد ، روی منبعِ پروپرتیِ DisplayMemberBinding ، تاثیری نداره .
بنابراین در این صورت ، منبعش برابر با اعضای کالکشنِ Data Source ئه کنترلِ والدش که در این مثال ، کنترل ListView هست ، میشه (یه روشِ تعیینِ Data Source ، میتونه در پروپرتیِ ItemsSource تعیین بشه) .

چه پروپرتیِ Source ئه Binding برای پروپرتیِ DisplayMemberBinding را تعیین کنیم ، یا منبعش را خودش از اعضای کالکشنِ Data Source ئه کنترلِ والدش بگیره ، در هر دو صورت ، تعداد اعضاش (تعداد سطرهاش) برابر با تعداد اعضای کالکشن مون (در اینجا ، در پروپرتیِ ItemsSource) میشه .

درست گفتم؟
تشکر استاد .
 

SajjadKhati

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

استاد ، توی آموزشم بخوام مزایای MVVM را نام ببرم (و اینکه در عمل ، فرقش با حالت غیر از MVVM چیه) ، این چیزهایی که میگم را ببینید درسته بی زحمت؟ :

معماری MVVM ، ارتباط مستقیمی که بین View با Model هست را قطع میکنه . این ارتباط ، بصورت غیر مستقیم در MVVM با اضافه شدن لایه ی ViewModel برقرار میشه که وظیفه اش ارتباط برقرار کردن و ارسالِ داده های مورد نیاز بین دو لایه ی View با Model هست .

مزیت این کار اینه که :
اولا تغییر دادن در لایه های View و Model ، آسون تر میشه و با ارور کمتری در ارتباط با این لایه ها مواجه میشه (نه اینکه اصلا ارورهای این لایه ها وجود نداشته باشه) . و راحت تر میتونیم View ئه فعلی مون را با View ی سازگارِ دیگه ای ، جایگزین کنیم . و همچنین Model ئه فعلی مون را با Model ئه سازگار دیگه ای ، جایگزین کنیم .

دوم اینکه وقتی تغییری (در View یا Model) داده میشه ، اگه ارورهایی بوجود بیاد ، اغلب متمرکز و مربوط به لایه ی ViewModel مون میشه . رفعِ این ارورهایی که متمرکز بر یک لایه هستن ، راحت تر از اینه که ارورها در لایه های View و Model ، پراکنده باشن .

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

و همچنین :

با پیاده سازی معماری MVVM در پروژه ، منطق تجاری با رابط کاربری ، از هم جدا میشن و به این ترتیب ، برنامه نویس میتونه منطق تجاری برنامه ، و طراح میتونه ظاهر کاربری برنامه را همزمان با هم انجام بدن .

همچنین این معماری ، قابلیت نگهداری و به روزرسانی (که در بالا توضیح داده شد) و unit testing برنامه را بهبود میبخشه .

بخاطر Binding بهتر و استفاده از Command ها در WPF ، پیاده سازی معماری MVVM در WPF ، راحت تر از پیاده سازی این معماری در WinForm هست .

اینها درست هستن استاد؟
تشکر استاد .
 

the_king

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

اما نکته ی مهم اینجاست که منبع ئه Binding (که برای پروپرتیِ DisplayMemberBinding نوشتیم) ، برخلاف منبعِ کنترل های عادی که از DataContext ئه کنترل والدشون پیروی میکنن ، منبعِ این پروپرتیِ DisplayMemberBinding ، از DataContext ای که قبلا برای کنترل والدش (مثلا DataContext برای کنترل Window در همون پروژه) تعریف کردیم ، پیروی نمیکنه .
اگر توضیحی می دهید که x برخلاف y از قاعده z پیروی نمی کنه باید یک تشابه موضوعی بین x و y باشه، وگرنه اگر x و y در یک گروه متناسب با z قرار نگیرند صدق کردن z برای y منطقی نداره که صدق نکردنش نیاز به مطرح کردن داشته باشه. مثل اینکه بگید کفش برخلاف حیوانات خانگی مرسوم بازیگوشی نمی کنه، کفش که حیوان خانگی نیست که پیروی نکردنش از قواعد حیوان خانگی عجیب باشه.
GridView و GridViewItem و ... کنترل نیستند، پس مطرح کردن اینکه برخلاف کنترل های عادی چه قواعدی رو رعایت نمی کنند محلی از اعراب نداره.
یعنی تعیینِ DataContext در والد ، روی منبعِ پروپرتیِ DisplayMemberBinding ، تاثیری نداره.
طبعا نه.
بنابراین در این صورت ، منبعش برابر با اعضای کالکشنِ Data Source ئه کنترلِ والدش که در این مثال ، کنترل ListView هست ، میشه (یه روشِ تعیینِ Data Source ، میتونه در پروپرتیِ ItemsSource تعیین بشه).

چه پروپرتیِ Source ئه Binding برای پروپرتیِ DisplayMemberBinding را تعیین کنیم ، یا منبعش را خودش از اعضای کالکشنِ Data Source ئه کنترلِ والدش بگیره ، در هر دو صورت ، تعداد اعضاش (تعداد سطرهاش) برابر با تعداد اعضای کالکشن مون (در اینجا ، در پروپرتیِ ItemsSource) میشه .
بله.
 

SajjadKhati

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

جواب پست قبلی رو هم بی زحمت میدین؟
پست 769

تشکر استاد .
 

SajjadKhati

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

طبعا نه.

بله.

خیلی ممنون استاد .
خوب کنترل نباشن .
الان پروپرتیِ DisplayMemberBinding ئه GridViewColumn انگار فقط این طوره .
وگرنه منبعِ Binding در پروپرتیِ Header ئه GridViewColumn ، از DataContext ئه کنترل والدش پیروی میکنه (مثلا DataContext ای که در Window تعریف کرده باشیم) .

تشکر استاد .
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
بعد استاد ، منبعِ Binding (همون Target Binding Object) در پروپرتیِ DisplayMemberBinding ، فکر کنم کل کالکشن (در Data Source هایی مثل ItemsSource) باشه . نه آیتم های اون .
اما در Path ئه Binding در پروپرتیِ DisplayMemberBinding ، وقتی نامِ پروپرتی ای را مینویسیم که در این کالکشن وجود نداره ، همونطور که قبلا گفتید ، میره درونِ آیتم های اون کالکشن میگرده .

این درسته؟
تشکر استاد .
 

the_king

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

استاد ، توی آموزشم بخوام مزایای MVVM را نام ببرم (و اینکه در عمل ، فرقش با حالت غیر از MVVM چیه) ، این چیزهایی که میگم را ببینید درسته بی زحمت؟ :

معماری MVVM ، ارتباط مستقیمی که بین View با Model هست را قطع میکنه . این ارتباط ، بصورت غیر مستقیم در MVVM با اضافه شدن لایه ی ViewModel برقرار میشه که وظیفه اش ارتباط برقرار کردن و ارسالِ داده های مورد نیاز بین دو لایه ی View با Model هست .

مزیت این کار اینه که :
اولا تغییر دادن در لایه های View و Model ، آسون تر میشه و با ارور کمتری در ارتباط با این لایه ها مواجه میشه (نه اینکه اصلا ارورهای این لایه ها وجود نداشته باشه) . و راحت تر میتونیم View ئه فعلی مون را با View ی سازگارِ دیگه ای ، جایگزین کنیم . و همچنین Model ئه فعلی مون را با Model ئه سازگار دیگه ای ، جایگزین کنیم .

دوم اینکه وقتی تغییری (در View یا Model) داده میشه ، اگه ارورهایی بوجود بیاد ، اغلب متمرکز و مربوط به لایه ی ViewModel مون میشه . رفعِ این ارورهایی که متمرکز بر یک لایه هستن ، راحت تر از اینه که ارورها در لایه های View و Model ، پراکنده باشن .
---------------------------------------

و همچنین :

با پیاده سازی معماری MVVM در پروژه ، منطق تجاری با رابط کاربری ، از هم جدا میشن و به این ترتیب ، برنامه نویس میتونه منطق تجاری برنامه ، و طراح میتونه ظاهر کاربری برنامه را همزمان با هم انجام بدن .

همچنین این معماری ، قابلیت نگهداری و به روزرسانی (که در بالا توضیح داده شد) و unit testing برنامه را بهبود میبخشه .
مباحث کلی رو به درستی مطرح می کنید ولی برخی توضیح و مثال تون نه. روی Error تمرکز نکنید، Error نتیجه یک اشتباه ئه، و میزانش و رفع اش به توانایی و معلومات و تجربه فردی و تیمی بستگی داره، نه معماری.
نگهداری و ارتقاء پروژه راحت تر میشه، چون تغییر در یک لایه الزاما نیازی به تغییر در لایه دیگه ای نداره و جایگزینی یک لایه با نسخه دیگر با حداقل تغییرات امکان پذیر ئه. طراحی محدودیت های کمتری داره چون تیم های مستقل می توانند روی طراحی و توسعه لایه های جداگانه متمرکز بشوند.
با پیدایش تکنولوژی های جدیدتر برای یک لایه امکان بروز رسانی یک لایه از پروژه ساده تر ئه چون نیازی به تغییر در کل پروژه و سایر لایه ها نیست و ...

بخاطر Binding بهتر و استفاده از Command ها در WPF ، پیاده سازی معماری MVVM در WPF ، راحت تر از پیاده سازی این معماری در WinForm هست .
بله.
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
خوب کنترل نباشن .
الان پروپرتیِ DisplayMemberBinding ئه GridViewColumn انگار فقط این طوره .
مقایسه تون درست نیست، به مثال موردی که بستگی نداره. شما ممکنه انواع مثال ها رو پیدا کنید که در مورد x و y وضعیت مشابهی باشه، ولی همچنان مقایسه x و y درست نباشه.
وگرنه منبعِ Binding در پروپرتیِ Header ئه GridViewColumn ، از DataContext ئه کنترل والدش پیروی میکنه (مثلا DataContext ای که در Window تعریف کرده باشیم) .
چرا همه مسائل رو با هم قاطی می کنید؟ به Binding ربطی نداره. Binding یک موجودیت مستقل ئه، رفتارش ربطی به المنتی که برایش Binding نوشته میشه نداره. Binding در Header با Binding در DataContext یا در ItemsSource یا در هر مشخصه دیگری فرقی نداره. Binding فقط رابط ئه، تعیین کننده رفتار اون المنت نیست. رفتار GridViewColumn هم قرار نیست شبیه ListView یا سایر کنترل ها باشه، مقایسه شون هم بی معنی ئه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
بعد استاد ، منبعِ Binding (همون Target Binding Object) در پروپرتیِ DisplayMemberBinding ، فکر کنم کل کالکشن (در Data Source هایی مثل ItemsSource) باشه . نه آیتم های اون .
اما در Path ئه Binding در پروپرتیِ DisplayMemberBinding ، وقتی نامِ پروپرتی ای را مینویسیم که در این کالکشن وجود نداره ، همونطور که قبلا گفتید ، میره درونِ آیتم های اون کالکشن میگرده .

این درسته؟
تشکر استاد .

خیلی ممنون استاد .
این چی؟
تشکر .
 

the_king

مدیرکل انجمن
بعد استاد ، منبعِ Binding (همون Target Binding Object) در پروپرتیِ DisplayMemberBinding ، فکر کنم کل کالکشن (در Data Source هایی مثل ItemsSource) باشه . نه آیتم های اون.
اگر اینطوری که شما میگید باشه همینطور که در TextBlock رشته Color[] Array رو نشون میده :
XML:
    <Grid>
        <Grid.DataContext>
            <x:Array Type="Color">
                <Color>Yellow</Color>
                <Color>Magenta</Color>
            </x:Array>
        </Grid.DataContext>
        <TextBlock Text="{Binding}"/>
    </Grid>
در متن سطر های ListView هم رشته Color[] Array رو باید نشون بده :
XML:
        <ListView>
            <ListView.ItemsSource>
                <x:Array Type="Color">
                    <Color>Yellow</Color>
                    <Color>Magenta</Color>
                </x:Array>           
            </ListView.ItemsSource>
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Width="300" Header="Color" DisplayMemberBinding="{Binding}"/>
                    </GridView.Columns>
                </GridView>
            </ListView.View>
        </ListView>
اما در Path ئه Binding در پروپرتیِ DisplayMemberBinding ، وقتی نامِ پروپرتی ای را مینویسیم که در این کالکشن وجود نداره ، همونطور که قبلا گفتید ، میره درونِ آیتم های اون کالکشن میگرده .
این درسته؟
چرا فرضیه می سازید و از من می پرسید درسته یا نه؟ من بگم چیزی درسته درست میشه؟ نظر من که نباید دلیل درستی فرضیه باشه.
خیر. فرضیه بافی نکنید، کدی متناسب با فرضیه بنویسید و اجرا کنید و ببینید نتیجه با چیزی که فکر می کنید جور در میاد یا نه.
C#:
using System.Collections;

namespace WpfApp1
{
    public class MyClass : IEnumerable
    {
        public class MySubClass
        {
            public string MyName => "MySubClass";
        }

        private readonly MySubClass[] _array = new MySubClass[] { new MySubClass(), new MySubClass(), new MySubClass() };

        public string MyName => "MyClass";

        public override string ToString()
        {
            return MyName;
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return _array.GetEnumerator();
        }
    }
}
اگر گفته شما درست باشه همانطور که در MyClass مشخصه MyName هست و نشون اش میده :
XML:
    <Grid>
        <Grid.DataContext>
            <local:MyClass/>
        </Grid.DataContext>
        <TextBlock Text="{Binding}"/>
    </Grid>
باید در ListView هم همون MyName ئه MyClass رو نشون بده، نه مشخصه MyName ئه MySubClass
XML:
        <ListView>
            <ListView.ItemsSource>
                <local:MyClass/>
            </ListView.ItemsSource>
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Width="300" Header="MyName" DisplayMemberBinding="{Binding MyName}"/>
                    </GridView.Columns>
                </GridView>
            </ListView.View>
        </ListView>
 

SajjadKhati

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

هم چیزهایی که شما گفتین ، هم چیزی که در لینک زیر گفت :


هم اینکه یه نفری در انجمن برنامه نویس یه سئوالی مطرح کرد که داشتم چک میکردم و کدش را این جوری تغییر دادم :

XML:
        <Grid.Resources>
            <x:Array x:Key="myTabItem" Type="{x:Type Button}">
                <Button Width="50" Height="50" Content="salam"/>
                <Button Width="50" Height="50" Content="Khobi?"/>
            </x:Array>
        </Grid.Resources>
        
        
        
                <TabControl Margin="0,  400, 0, 0" Height="200" ItemsSource="{Binding Source={StaticResource myTabItem}}">
            <TabControl.ItemContainerStyle>
                <Style TargetType="{x:Type TabItem}">
                    <Setter Property="Header" Value="{Binding Path=Content}"/>
                    <Setter Property="Content" Value="{Binding }"/>
                </Style>
            </TabControl.ItemContainerStyle>
        </TabControl>

از همه ی اینها نتیجه ام این شد ، ببینید درسته؟ :

اینکه پروپرتی هایی که در توضیحات شون که گفته شده که "برای Bind شدن به Data Item ها (آیتم ها) استفاده میشن" ، مثل توضیحِ پروپرتیِ DisplayMemberBinding ، و همچنین پروپرتی های مربوط به اشیاهایی که مربوط به فرضا ComboBoxItem ، ListBoxItem ، TabItem و از این نوع کنترل هایی که آیتم هایی را برای کنترل های ItemsControl مشخص میکنن (فرضا همین پروپرتیِ Header و Content ئه TabItem که در کد بالا براش Binding انجام شده) ،
اگه برای این نوع پروپرتی ها Binding انجام بشه و همچنین اگه برای کنترل مربوطه (مثلا کنترل TabControl و ...) ، پروپرتیِ ItemsSource را مقداردهی کنیم ، مقدار پیش فرضِ Source ئه Binding در این پروپرتی ها ، برابر با دونه دونه ی آیتم هایی هست که در پروپرتیِ ItemsSource مشخص شد (که اگه برای پروپرتیِ ItemsSource ، عمل Binding اانجام بدیم ، معمولا آیتم های ItemsSource را ، مقدار پروپرتیِ Path ئه Binding اش مشخص میکنه و بنابراین در این صورت ، مقدار پیش فرضِ Source ئه Binding در پروپرتی هایی مثل DisplayMemberBinding و Header و Content که در بالا گفته شد ، برابر با پروپرتیِ Path ئه Binding ئه ItemsSource در دونه دونه آیتم هاشون میشه) .

یعنی در این حالت ، Source ئه Binding ئه این پروپرتی ها ، برابر با منبعی که در DataContext مشخص کرده بودیم ، نمیشه و DataContext روشون تاثیری نداره اما بجز این پروپرتی ها ، Source ئه Binding ئه بقیه ی پروپرتی ها ، از پروپرتیِ DataContext بصورت پیش فرض گرفته میشه (البته غیر از Template ها و اینها) .

اینکه Source ئه Binding در پروپرتی هایی مثل Header ئه GridViewColumn ، چرا از آیتم های ItemsSource گرفته نمیشه و از DataContext گرفته میشه (با اونکه Source ئه Binding ئه DisplayMemberBinding که هر دو عضو GridViewColumn هستند ، برعکسش هست) ، بخاطر اینکه در توضیحات پروپرتی اش چیزی درباره ی استفاده و bind شدن به Data Item (آیتم ها) نگفت .

درست گفتم .
تشکر استاد .
 

the_king

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

هم چیزهایی که شما گفتین ، هم چیزی که در لینک زیر گفت :


هم اینکه یه نفری در انجمن برنامه نویس یه سئوالی مطرح کرد که داشتم چک میکردم و کدش را این جوری تغییر دادم :

XML:
        <Grid.Resources>
            <x:Array x:Key="myTabItem" Type="{x:Type Button}">
                <Button Width="50" Height="50" Content="salam"/>
                <Button Width="50" Height="50" Content="Khobi?"/>
            </x:Array>
        </Grid.Resources>
       
       
       
                <TabControl Margin="0,  400, 0, 0" Height="200" ItemsSource="{Binding Source={StaticResource myTabItem}}">
            <TabControl.ItemContainerStyle>
                <Style TargetType="{x:Type TabItem}">
                    <Setter Property="Header" Value="{Binding Path=Content}"/>
                    <Setter Property="Content" Value="{Binding }"/>
                </Style>
            </TabControl.ItemContainerStyle>
        </TabControl>

از همه ی اینها نتیجه ام این شد ، ببینید درسته؟ :

اینکه پروپرتی هایی که در توضیحات شون که گفته شده که "برای Bind شدن به Data Item ها (آیتم ها) استفاده میشن" ، مثل توضیحِ پروپرتیِ DisplayMemberBinding ، و همچنین پروپرتی های مربوط به اشیاهایی که مربوط به فرضا ComboBoxItem ، ListBoxItem ، TabItem و از این نوع کنترل هایی که آیتم هایی را برای کنترل های ItemsControl مشخص میکنن (فرضا همین پروپرتیِ Header و Content ئه TabItem که در کد بالا براش Binding انجام شده) ،
اگه برای این نوع پروپرتی ها Binding انجام بشه و همچنین اگه برای کنترل مربوطه (مثلا کنترل TabControl و ...) ، پروپرتیِ ItemsSource را مقداردهی کنیم ، مقدار پیش فرضِ Source ئه Binding در این پروپرتی ها ، برابر با دونه دونه ی آیتم هایی هست که در پروپرتیِ ItemsSource مشخص شد (که اگه برای پروپرتیِ ItemsSource ، عمل Binding اانجام بدیم ، معمولا آیتم های ItemsSource را ، مقدار پروپرتیِ Path ئه Binding اش مشخص میکنه و بنابراین در این صورت ، مقدار پیش فرضِ Source ئه Binding در پروپرتی هایی مثل DisplayMemberBinding و Header و Content که در بالا گفته شد ، برابر با پروپرتیِ Path ئه Binding ئه ItemsSource در دونه دونه آیتم هاشون میشه) .

یعنی در این حالت ، Source ئه Binding ئه این پروپرتی ها ، برابر با منبعی که در DataContext مشخص کرده بودیم ، نمیشه و DataContext روشون تاثیری نداره اما بجز این پروپرتی ها ، Source ئه Binding ئه بقیه ی پروپرتی ها ، از پروپرتیِ DataContext بصورت پیش فرض گرفته میشه (البته غیر از Template ها و اینها) .
من از روی این نشونه ها تصمیم نمی گیرم. اگه به کاری که مشخصه قراره بکنه توجه کنید، خودش مشخص میکنه که منبع داده اش چی میتونه باشه یا بصورت پیشفرض چی رو نمایش میده. فرضا اگر مشخصه ای قراره محتویات سطر جدول رو تعیین کنه بدیهی است که باید منبع اش اعضاء سطر باشه.
اینکه Source ئه Binding در پروپرتی هایی مثل Header ئه GridViewColumn ، چرا از آیتم های ItemsSource گرفته نمیشه و از DataContext گرفته میشه (با اونکه Source ئه Binding ئه DisplayMemberBinding که هر دو عضو GridViewColumn هستند ، برعکسش هست) ، بخاطر اینکه در توضیحات پروپرتی اش چیزی درباره ی استفاده و bind شدن به Data Item (آیتم ها) نگفت .
چون نه GridViewColumn فرزند درخت بصری ListView ئه و نه Header با ItemsSource ئه ListView کاری داره. در نظر بگیرید که GridViewColumn فقط توصیف ستونی از GridView ئه، کنترل نیست، کنترلی که داخل ListView باشه نیست. برای همین Source ئه یک Binding در Header بصورت پیشفرض چیزی است که در توصیف المنت های والد به عنوان DataContext مطرح شده. وگرنه کنترل والدی نداره که بخواد منبع داده اش رو از اون بگیره. اما DisplayMemberBinding قراره محتویات سطر رو نشون بده، به آیتم هایی که داخل ListView نمایش داده میشه مربوطه، برای همین باید منبع داده اش اعضاء اون باشه.
 

SajjadKhati

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

اول روی دکمه ای که محتواش نوشته "Mouse Enter Change Student Member Value" برید (دکمه ی بالا سمت راست) :

- حالا اگه روی کنترل ListView موس را روی آیتم های مختلف ببرید ، چون در رویداد ListViewItem_MouseEnter ، با متد ICollectionView.MoveCurrentTo ، مقدارِ پروپرتیِ CurrentItem ئه CollectionView ی پیش فرض را تغییر دادم ، خوب مشخص هست که چون پروپرتیِ Header ئه شیِ سوم از GridViewColumn (در کنترل ListView) ، به CurrentItem متصل و Binding شد ، مقدارش به همونی که در اون متد داده بودیم ، تغییر میکنه .

- اما وقتی که اون کد ، یعنی متد ICollectionView.MoveCurrentTo در رویداد ListViewItem_MouseEnter را کامنت (یا حذف) کنید و همچنین اگه روی آیتم های ListView ، کلیک کنید ، این اتفاق نمیافته و CurrentItem تغییر نمیکنه . که شاید طبیعی به نظر برسه .

اما من جایی خونده بودم (اگه درست یادم بیاد) که کاربر نهایی با کلیک و انتخاب آیتم ها (در کنترل هایی که به یه کالکشن ای Binding شدن) ، باعث میشه تا پروپرتیِ CurrentItem ئه اون CollectionView بصورت اتوماتیک به همون آیتم ، تغییر مقدار بده .
حالا نمیدونم برداشت من از اون مطلب اشتباه بوده یا جریان چیز دیگه ای هست؟
تشکر استاد .
 

پیوست ها

  • MVVM_Practies.rar
    1.9 مگایابت · بازدیدها: 1

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

بالا