2009-10-28 14 views
10

मैं ब्लैकआउटडेट्स संपत्ति की तिथियों की एक सूची बांधना चाहता हूं लेकिन यह वास्तव में संभव नहीं लगता है। विशेष रूप से एक एमवीवीएम परिदृश्य में। क्या किसी ने ऐसा कुछ किया है? क्या कोई अच्छा कैलेंडर नियंत्रण है जो एमवीवीएम के साथ अच्छा खेलता है? (CommandBindings के अपने प्रयोग से संशोधित)WPF टूलकिट कैलेंडर नियंत्रण में ब्लैकआउटडेट्स को कैसे बाध्य करें?

+0

क्या होता है जब आप BlackoutDates करने के लिए बाध्य करने की कोशिश? क्या आपको कोई त्रुटि मिल रही है? – user200783

+0

कोई ब्लैकआउटडेट्स भी एक विकल्प नहीं है ... मुझे लगता है कि मैं डेटपिकर का उपयोग कर रहा हूं, लेकिन मैंने सोचा कि अभी कैलेंडर और टेक्स्टबॉक्स का उपयोग किया गया है। – nportelli

उत्तर

16

अपने DatePicker दुविधा के लिए, मैं एक साफ हैक संलग्न गुण का उपयोग कर पाया:

class AttachedProperties : DependencyObject 
{ 

    #region RegisterBlackoutDates 

    // Adds a collection of command bindings to a date picker's existing BlackoutDates collection, since the collections are immutable and can't be bound to otherwise. 
    // 
    // Usage: <DatePicker hacks:AttachedProperties.RegisterBlackoutDates="{Binding BlackoutDates}" > 

    public static DependencyProperty RegisterBlackoutDatesProperty = DependencyProperty.RegisterAttached("RegisterBlackoutDates", typeof(System.Windows.Controls.CalendarBlackoutDatesCollection), typeof(AttachedProperties), new PropertyMetadata(null, OnRegisterCommandBindingChanged)); 

    public static void SetRegisterBlackoutDates(UIElement element, System.Windows.Controls.CalendarBlackoutDatesCollection value) 
    { 
     if (element != null) 
      element.SetValue(RegisterBlackoutDatesProperty, value); 
    } 
    public static System.Windows.Controls.CalendarBlackoutDatesCollection GetRegisterBlackoutDates(UIElement element) 
    { 
     return (element != null ? (System.Windows.Controls.CalendarBlackoutDatesCollection)element.GetValue(RegisterBlackoutDatesProperty) : null); 
    } 
    private static void OnRegisterCommandBindingChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    { 
     System.Windows.Controls.DatePicker element = sender as System.Windows.Controls.DatePicker; 
     if (element != null) 
     { 
      System.Windows.Controls.CalendarBlackoutDatesCollection bindings = e.NewValue as System.Windows.Controls.CalendarBlackoutDatesCollection; 
      if (bindings != null) 
      { 
       element.BlackoutDates.Clear(); 
       foreach (var dateRange in bindings) 
       { 
        element.BlackoutDates.Add(dateRange); 
       } 
      } 
     } 
    } 

    #endregion 
} 

मुझे यकीन है कि मैं तुम्हें मदद करने के लिए बहुत देर हो चुकी है, लेकिन उम्मीद है कि किसी को कर रहा हूँ कर रहा हूँ अन्यथा यह उपयोगी लगेगा।

+0

उस परियोजना को समय के लिए पकड़ा नहीं गया था। मुझे यकीन नहीं है कि मैं अभी तक संलग्न गुणों को समझता हूं, लेकिन मैंने सोचा कि यह करने का एक तरीका था, मुझे अभी नहीं पता था कि उस समय कैसे। डब्ल्यूपीएफ बैंडवैगन पर वापस आने का समय। – nportelli

+0

हाँ, मैं 100% निश्चित नहीं हूं, मुझे अभी तक संलग्न गुण मिलते हैं - लेकिन ऐसा लगता है कि दो उपयोग हैं: 1. अतिरिक्त डेटा (जैसे कैनवास ऑब्जेक्ट), या 2 के लिए एक डायनामिक-ऑब्जेक्ट-कीड डिक्शनरी का विकल्प XAML से एक विस्तार-विधि-जैसे उपयोग। हम्म, इस विषय पर एक समुदाय विकी वास्तव में दिलचस्प हो सकता है। –

6

मैंने उपर्युक्त उदाहरण (संलग्नप्रॉपर्टीज क्लास) लागू किया।

public CalendarBlackoutDatesCollection BlackoutDates 
    { 
     get 
     { 
      return _blackoutDates; 
     } 
     set 
     { 
      _blackoutDates = value; 
      this.RaisePropertyChanged(p => p.BlackoutDates); 
     } 
    } 

यह ViewModel inerits ObservableBase से: मैं इस तरह मेरी ViewModel में एक संपत्ति बनाई

using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.ComponentModel; 
    using System.Windows.Data; 
    using System.Collections; 

    namespace MySolution 
    { 
     public abstract class ObservableBase : INotifyPropertyChanged 
     { 
      public event PropertyChangedEventHandler PropertyChanged; 

      public void RaisePropertyChanged(string propertyName) 
      { 
       if (this.PropertyChanged != null) 
       { 
        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
       } 
      } 
     } 
    } 

यह वह जगह है विंडो में Xaml इस संपत्ति का उपयोग करता है: अब

<Window x:Class="MySolution.MainWindow" 

    xmlns:local="clr-namespace:MySolution"> 
    <Grid> 
        <DatePicker x:Name="datePicker" Grid.Row="0" Height="30" 
           local:AttachedProperties.RegisterBlackoutDates="{Binding BlackoutDates}"> 
        </DatePicker> 
    </Grid> 

जब मैं कैलेंडर में ब्लैकआउटडेट्स जोड़ना चाहता हूं, तो मैं अपने ViewModel में UpdateCalendarBlackoutDates को कॉल करता हूं:

private void UpdateCalendarBlackoutDates() 
    { 
     CalendarDateRange r = new CalendarDateRange(new DateTime(2010, 12, 9), new DateTime(2010, 12, 9)); 
     CalendarDateRange r2 = new CalendarDateRange(new DateTime(2010, 12, 10), new DateTime(2010, 12, 10)); 
     // Because we can't reach the real calendar from the viewmodel, and we can't create a 
     // new CalendarBlackoutDatesCollection without specifying a Calendar to 
     // the constructor, we provide a "Dummy calendar", only to satisfy 
     // the CalendarBlackoutDatesCollection... 
     // because you can't do: BlackoutDates = new CalendarBlackoutDatesCollection(). 
     Calendar dummyCal = new Calendar(); 
     BlackoutDates = new CalendarBlackoutDatesCollection(dummyCal); 
     // Add the dateranges to the BlackOutDates property 
     BlackoutDates.Add(r); 
     BlackoutDates.Add(r2); 
    } 

यह मेरे लिए पूरी तरह से काम करता है। यह आगे OnRegisterCommandBindingChanged विधि बदलते एक CalendarBlackoutDatesCollection के बजाय DateRanges की एक सूची स्वीकार करने के लिए है, और इस तरह एक सूची के लिए संपत्ति को बदलने के द्वारा सिद्ध किया जा सकता है:

public List<CalendarDateRange> BlackoutDates 
{ 
    etc. 

लेकिन अब यह मेरे लिए काम करता है के लिए ..

+0

यह मेरे लिए काम किया, धन्यवाद। – dev1998

8

मैट के उत्तर का एक बेहतर संस्करण है जो हमें ब्लैकआउटडेट्स के साथ किसी भी सामान्य पर्यवेक्षण संग्रह के साथ काम करने की अनुमति देता है (जब भी आप ब्लैकआउटडेट्स को बदलना चाहते हैं तो आपको नए संग्रह बनाने की आवश्यकता नहीं है)। हम सभी कैलेंडरों और डेटपिकर्स की एक सूची संग्रहित करते हैं और उनके टैग के अंदर हम संग्रह को संग्रहीत करते हैं जो एमवीवीएम में उपयोग किया जाता है। वर्ग के लिए एक आसान संशोधन ObservableCollection < दिनांक समय > साथ काम करने के यदि आवश्यक हो तो अनुमति देगा:

// Adds a collection of command bindings to a date picker's existing BlackoutDates collection, since the collections are immutable and can't be bound to otherwise. 
// Usage: <DatePicker CalendarAttachedProperties.RegisterBlackoutDates="{Binding BlackoutDates}" > 
public class CalendarAttachedProperties : DependencyObject 
{ 
    #region Attributes 

    private static readonly List<Calendar> _calendars = new List<Calendar>(); 
    private static readonly List<DatePicker> _datePickers = new List<DatePicker>(); 

    #endregion 

    #region Dependency Properties 

    public static DependencyProperty RegisterBlackoutDatesProperty = DependencyProperty.RegisterAttached("RegisterBlackoutDates", typeof(CalendarBlackoutDatesCollection), typeof(CalendarAttachedProperties), new PropertyMetadata(null, OnRegisterCommandBindingChanged)); 

    public static void SetRegisterBlackoutDates(DependencyObject d, CalendarBlackoutDatesCollection value) 
    { 
     d.SetValue(RegisterBlackoutDatesProperty, value); 
    } 

    public static CalendarBlackoutDatesCollection GetRegisterBlackoutDates(DependencyObject d) 
    { 
     return (CalendarBlackoutDatesCollection)d.GetValue(RegisterBlackoutDatesProperty); 
    } 

    #endregion 

    #region Event Handlers 

    private static void CalendarBindings_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     CalendarBlackoutDatesCollection blackoutDates = sender as CalendarBlackoutDatesCollection; 

     Calendar calendar = _calendars.First(c => c.Tag == blackoutDates); 

     if (e.Action == NotifyCollectionChangedAction.Add) 
     { 
      foreach (CalendarDateRange dateRange in e.NewItems) 
      { 
       calendar.BlackoutDates.Add(dateRange); 
      } 
     } 
    } 

    private static void DatePickerBindings_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     CalendarBlackoutDatesCollection blackoutDates = sender as CalendarBlackoutDatesCollection; 

     DatePicker datePicker = _datePickers.First(c => c.Tag == blackoutDates); 

     if (e.Action == NotifyCollectionChangedAction.Add) 
     { 
      foreach (CalendarDateRange dateRange in e.NewItems) 
      { 
       datePicker.BlackoutDates.Add(dateRange); 
      } 
     } 
    } 

    #endregion 

    #region Private Methods 

    private static void OnRegisterCommandBindingChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    { 
     Calendar calendar = sender as Calendar; 
     if (calendar != null) 
     { 
      CalendarBlackoutDatesCollection bindings = e.NewValue as CalendarBlackoutDatesCollection; 
      if (bindings != null) 
      { 
       if (!_calendars.Contains(calendar)) 
       { 
        calendar.Tag = bindings; 
        _calendars.Add(calendar); 
       } 

       calendar.BlackoutDates.Clear(); 
       foreach (var dateRange in bindings) 
       { 
        calendar.BlackoutDates.Add(dateRange); 
       } 
       bindings.CollectionChanged += CalendarBindings_CollectionChanged; 
      } 
     } 
     else 
     { 
      DatePicker datePicker = sender as DatePicker; 
      if (datePicker != null) 
      { 
       CalendarBlackoutDatesCollection bindings = e.NewValue as CalendarBlackoutDatesCollection; 
       if (bindings != null) 
       { 
        if (!_datePickers.Contains(datePicker)) 
        { 
         datePicker.Tag = bindings; 
         _datePickers.Add(datePicker); 
        } 

        datePicker.BlackoutDates.Clear(); 
        foreach (var dateRange in bindings) 
        { 
         datePicker.BlackoutDates.Add(dateRange); 
        } 
        bindings.CollectionChanged += DatePickerBindings_CollectionChanged; 
       } 
      } 
     } 
    } 

    #endregion 
} 

यहाँ ObservableCollection < दिनांक समय > संस्करण है:

// Adds a collection of command bindings to a date picker's existing BlackoutDates collection, since the collections are immutable and can't be bound to otherwise. 
// Usage: <DatePicker hacks:AttachedProperties.RegisterBlackoutDates="{Binding BlackoutDates}" > 
public class CalendarAttachedProperties : DependencyObject 
{ 
    #region Attributes 

    private static readonly List<Calendar> _calendars = new List<Calendar>(); 
    private static readonly List<DatePicker> _datePickers = new List<DatePicker>(); 

    #endregion 

    #region Dependency Properties 

    public static DependencyProperty RegisterBlackoutDatesProperty = DependencyProperty.RegisterAttached("RegisterBlackoutDates", typeof(ObservableCollection<DateTime>), typeof(CalendarAttachedProperties), new PropertyMetadata(null, OnRegisterCommandBindingChanged)); 

    public static void SetRegisterBlackoutDates(DependencyObject d, ObservableCollection<DateTime> value) 
    { 
     d.SetValue(RegisterBlackoutDatesProperty, value); 
    } 

    public static ObservableCollection<DateTime> GetRegisterBlackoutDates(DependencyObject d) 
    { 
     return (ObservableCollection<DateTime>)d.GetValue(RegisterBlackoutDatesProperty); 
    } 

    #endregion 

    #region Event Handlers 

    private static void CalendarBindings_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     ObservableCollection<DateTime> blackoutDates = sender as ObservableCollection<DateTime>; 

     Calendar calendar = _calendars.First(c => c.Tag == blackoutDates); 

     if (e.Action == NotifyCollectionChangedAction.Add) 
     { 
      foreach (DateTime date in e.NewItems) 
      { 
       calendar.BlackoutDates.Add(new CalendarDateRange(date)); 
      } 
     } 
    } 

    private static void DatePickerBindings_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     ObservableCollection<DateTime> blackoutDates = sender as ObservableCollection<DateTime>; 

     DatePicker datePicker = _datePickers.First(c => c.Tag == blackoutDates); 

     if (e.Action == NotifyCollectionChangedAction.Add) 
     { 
      foreach (DateTime date in e.NewItems) 
      { 
       datePicker.BlackoutDates.Add(new CalendarDateRange(date)); 
      } 
     } 
    } 

    #endregion 

    #region Private Methods 

    private static void OnRegisterCommandBindingChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    { 
     Calendar calendar = sender as Calendar; 
     if (calendar != null) 
     { 
      ObservableCollection<DateTime> bindings = e.NewValue as ObservableCollection<DateTime>; 
      if (bindings != null) 
      { 
       if (!_calendars.Contains(calendar)) 
       { 
        calendar.Tag = bindings; 
        _calendars.Add(calendar); 
       } 

       calendar.BlackoutDates.Clear(); 
       foreach (DateTime date in bindings) 
       { 
        calendar.BlackoutDates.Add(new CalendarDateRange(date)); 
       } 
       bindings.CollectionChanged += CalendarBindings_CollectionChanged; 
      } 
     } 
     else 
     { 
      DatePicker datePicker = sender as DatePicker; 
      if (datePicker != null) 
      { 
       ObservableCollection<DateTime> bindings = e.NewValue as ObservableCollection<DateTime>; 
       if (bindings != null) 
       { 
        if (!_datePickers.Contains(datePicker)) 
        { 
         datePicker.Tag = bindings; 
         _datePickers.Add(datePicker); 
        } 

        datePicker.BlackoutDates.Clear(); 
        foreach (DateTime date in bindings) 
        { 
         datePicker.BlackoutDates.Add(new CalendarDateRange(date)); 
        } 
        bindings.CollectionChanged += DatePickerBindings_CollectionChanged; 
       } 
      } 
     } 
    } 

    #endregion 
} 
संबंधित मुद्दे