View Full Version : Binding for FlowDirection
powerboy2988
یک شنبه 15 مرداد 1391, 10:00 صبح
سلام
من می خوام برای Globalization تو لایه ModelView به خاصیت FlowDirection یک window مقدار بدم که با تغییر زبان، عوض بشه...
کاری که می کنم تو ModelView :
private FlowDirection _windowsMain;
public FlowDirection WindowsMain
{
get { return _windowsMain; }
set
{
if (_windowsMain == value) return;
_windowsMain = value;
this.OnPropertyChanged("WindowsMain");
}
}
private ComboBoxItem _currentItem;
public ComboBoxItem CurrentItem
{
get { return _currentItem; }
set
{
if (_currentItem == value) return;
_currentItem = value;
this.OnPropertyChanged("CurrentItem");
SetLocalization(_currentItem.Content.ToString());
}
}
private void SetLocalization(string _culture)
{
ResourceDictionary dict = new ResourceDictionary();
if (!_culture.Equals("English"))
{
dict.Source = new Uri("..\\Assets\\StaticText_fa.xaml", UriKind.Relative);
_windowsMain = System.Windows.FlowDirection.RightToLeft;
}
else
{
dict.Source = new Uri("..\\Assets\\StaticText.xaml", UriKind.Relative);
_windowsMain = System.Windows.FlowDirection.LeftToRight;
}
}
و در View :
<Window x:Class="Sample.View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:IrdenSys.Commands"
Height="260" Width="440"
Name="WindowsMain" Icon="/Assets/Images/irden.ico" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" WindowStyle="None" Background="#FFA7A7A7" FlowDirection="{Binding WindowsMain,Mode=TwoWay}">
اما اصلا تغییری حاصل نمی شه!! باید از Converter استفاده کنم؟؟
ممنون میشم که راهنمایی کنید..
Amir Oveisi
یک شنبه 15 مرداد 1391, 21:04 عصر
به ظاهر که درسته و من تو یه پروژه دیگه تست کردم و مشکلی نداشت. احتمالا مشکل از جای دیگه ای باشه. اگر تونستید پروژه رو قرار بدید تا بررسی کنم.
در ضمن چرا ComboBoxItem در viewmodel تعریف کردید؟
powerboy2988
دوشنبه 16 مرداد 1391, 09:02 صبح
به ظاهر که درسته و من تو یه پروژه دیگه تست کردم و مشکلی نداشت. احتمالا مشکل از جای دیگه ای باشه. اگر تونستید پروژه رو قرار بدید تا بررسی کنم.
در ضمن چرا ComboBoxItem در viewmodel تعریف کردید؟
مشکلم تو این بود که باید مستقیم خود CurrentItem رو مقدار دهی کنم نه currentItem_ رو...
چون می خواستم مقدار Combo box رو بخونم از این روش استفاده کردم... باید از Converter استفاده کنم؟؟
sia_2007
دوشنبه 16 مرداد 1391, 18:58 عصر
باید از یه Collection ای استفاده کنی که MVVM Friendly باشه، و Current رو بهت بده، اسمش رو بدبختانه یادم نمی آد
بعد اون Collection رو به Items Source کنترل Combo Box ات Bind کنی
Domain Collection View گزینه خوبیه، ولی برای کار با اطلاعاتی که از سرور می آن، این یه دیتای معمولیه، بگرد، پیدا می کنی
Amir Oveisi
پنج شنبه 19 مرداد 1391, 09:15 صبح
مشکلم تو این بود که باید مستقیم خود CurrentItem رو مقدار دهی کنم نه currentItem_ رو...
چون می خواستم مقدار Combo box رو بخونم از این روش استفاده کردم... باید از Converter استفاده کنم؟؟
ببینید، منطق اتون برای این کار درست نیست.
شما نباید اصلا تو view-model بیاید و از نوع داده های View (مثل کنترل ها) object ای بسازید و باهاش کار کنید. چرا؟ چون لایه view-model شما اصلا نباید بدونه که کسی به نام view وجود داره! چه برسه به اینکه بدونه ComboBox هم داره...
اصولا برای اینکه بتونید این مشکل رو رفع کنید باید به یه نکته توجه داشته باشید که در همه List Control ها (اونایی که از ItemsControl ارث بردن) شما یک سری آیتم هایی دارید که همه ContentControl هستند و میتونید هر نوع داده ای داخلشون قرار بدید. مثلا فرض کنید شما کلاسی ساختید برای یک ماشین که اطلاعاتی مثل نام و رنگ و مدل و ... داره. لیستی از این ماشین ها رو می سازید (به هر طریقی، مثل خوندن از دیتابیس یا فیال یا ...) و به عنوان ItemsSource اون List Control ای که دارید Set می کنید و مشخصات اون ماشین ها تو آیتم ها نشون داده میشه. حالا چی اتفاقی افتاده؟ اینکه هر آیتم، نوع داده اش از نوع کلاس ماشین هست. ئس یعنی SelectedItem شما، از نوع کلاس ماشین هست و نیازی نیست حتما از نوع (مثلا) ComboBoxItem بسازید تا بتونید SelectedItem رو نگهداری کنید.
روش درست اینه که شما تو لایه view-model یک property از کلاس ماشین (که model محسوب میشه) بسازید و تو لایه view، مقدار SelectedItem اون ComboBox رو به property که واسه ماشین ساختید، bind کنید. هر موقع آیتمی از لیست انتخاب شد، مقدارش تو property ای که تو view-model هست، قرار میگیره.
موفق باشید
powerboy2988
پنج شنبه 19 مرداد 1391, 09:39 صبح
بله...
کاملا درسته و ممنون از راهنماییتون...
من حذفش کردم...
sia_2007
پنج شنبه 19 مرداد 1391, 15:45 عصر
من یه متن کامل نوشته بودم، که می تونست به خوبی مسائل رو توضیح بده، لکن دستم خورد روی Back و سایت برنامه نویس هم یه سوال نمی پرسه که اگه خارج شی اطلاعاتی که با زحمت تایپ کردی حذف می شه، ( مثل Word Press برای مثال )، الآن متاسفانه اون تایم رو دیگه ندارم، اما برای این که آقای اویسی متوجه اشتباه خودشون بشم، و سایر دوستان نیز از این پس راه درست رو برن، توصیه می کنم به این اینترفیس ها یه نگاهی بندازن :
ICollectionView
دارای قابلیت Sort، فیلتر، دسترسی به Current، و بسیاری امکانات دیگر
IEditableCollectionView
دارای قابلیت های بسیار بالا برای سناریوهای پیشرفته کار با Data و تغییرات بر روی آن
IPagedCollectionView
دارای قابلیت Paging و ...
حال اگه من جای شما بودم
کد رو به شکل زیر طراحی می کردم، البته من همه قواعد رو رعایت نکردم و کد زیر رو هم صد در صد صحیح نمی دونم
// Model :
public enum LanguageDirection
{
RTL, LTR // Left to right and right to left
}
public class Language : Entity
{
// ای که نوشتی بتونی ازش استفاده کنی Set Localize یک نام انگلیسی که در متد
// ات رو صحیح نمی دونم Set Localize هر چند من متد
// دارم می نویسم MVVM و این رو فقط برای آموزش
// هستش Proxy Pattern توسط INotifyPropertyChanged ها برای فراخوانی Virtual
public virtual String Name { get; set; }
// عنوان فارسی >> انگلیسی، فرانسوی، عربی، فارسی
public virtual String Title { get; set; } // Display Member Path به عنوان Combo Box برای نمایش در
// Set Localize برای استفاده در متد
public virtual LanguageDirection Direction { get; set; }
}
// End Of Model
public class ViewModel : ViewModelBase
{
public virtual ICollectionView Languages { get; set; }
public virtual LanguageDirection CurrentDirction { get; set; }
public ViewModel()
{
// Languages = new ((!! Any Class by ICollectionView implementation !!))
Languages.CurrentChanged += Languages_CurrentChanged;
}
void Languages_CurrentChanged(object sender, EventArgs e)
{
var currentLanguage = Languages.CurrentItem.As<Language>();
// الان هم
// currentLanguage.Name
// رو داری و هم
// currentLanguage.Direction
// CurrentDirction به Value Convertor ویندوت رو با یه FlowDirection نیست، فقط باید if اصلا نیازی به
// وصل کنی
// های چند زبانگی ات رو هم جوری بنویسی XML نام گذاری فایل های
// نباشه، if شون کنی و نیازی به Load بتونی currentLanguage.Name که با
// این طوری می تونی بی نهایت زبان داشته باشی
// در کل مجدد تاکید می کنم روشت کلا اشتباه است،
// اما این طوری حداقل خیلی بهتر می شه
// بزنی بهتره تا این که از Flow Direction ای با نام enum این که یه بار
// استفاده کنی WPF خود Flow Direction
}
}
امیدوارم مطلب مفید بوده باشه،
Amir Oveisi
جمعه 20 مرداد 1391, 10:00 صبح
اما برای این که آقای اویسی متوجه اشتباه خودشون بشن
ببخشید من متوجه اشتباه خودم نشدم. اگر بیشتر توضیح می دادید ممنون میشدم.
پ.ن:
به این نکته توجه کنید که موضوع این تاپیک در مورد نحوه پیاده سازی localization نبوده و در مورد نحوه bind کردن FlowDirection سوال پرسیده شده. :)
sia_2007
جمعه 20 مرداد 1391, 14:28 عصر
بله، خواهش می کنم
من خواستم مثالم رو کاربردی تر کرده باشم، وگرنه مسلما منظورم پیاده سازی چند زبانگی اونم به این روش نه چندان صحیح نیستش
ببینید، شما می گید برای نگهداری Current یه کمبو باکس، باید یه Current در View Model تعبیه بشه، در حالی که ایده من اینه که Collection ای در View Model به Items Source اون Combo Box بایند بشه، که یکی از قابلیت هاش Current هستش
در واقع جواب شماره 5 شما، تا آخرهاش که دارید اشتباه روش اون نفر اول رو می گید، کاملا درسته، اما راه حل خودتون نه این که اشتباه باشه، ولی لااقل سخته، چون Current یکی از نیازمندی هاست، من سایر نیازمندی ها رو هم ذکر کردم، بهتره رابطه بین View و View Model، مثل هر لایه ی دیگه ای با Interface باشه، این interface بین View و ViewModel مشترک باشه، و در سمت View پیاده سازی بشه، و در سمت View Model فراخونی بشه، دقیقا مثل Messenger ای که شما می تونید تو MVVM ازش استفاده کنید.
اگه به مثال من دقت کنی، من بدون یه Property اضافه، به Current دسترسی دارم و علاوه بر اون کلی دیگه از امکانات ICollectionView رو هم دارم
اگه باز هم امکانات بیشتری بخوام از interface سطح بالاتری استفاده می کنم.
باز هم لازم باشه می تونم بیشتر توضیح بدم، به صورت تلفنی هم برام مقدوره
Amir Oveisi
جمعه 20 مرداد 1391, 17:54 عصر
با تشکر از توضیحات شما عرض کنم که بنده از قابلیت های ICollectionView اطلاع دارم و در مواردی که با لیست ها سر و کار داریم خیلی مفید هستند و حرف شما کاملا درسته.
در واقع من هدفم از اون مثال صرفا بیان ساده این مطلب بود که رابط کلیدی بین view و view model استفاده از property ها و binding ها است. و در استفاده از property ها هم نباید درگیر UIElement های موجود در view بشیم.
باز هم ممنون از توضیحاتی که ارائه کردید.
موفق باشید
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.