locked
convert to vb RRS feed

  • Question

  • Hi All.

    I unsuccessfully tried to convert that code on some web site. Most problem on 4th procedure

    public class DatePickerHelper
       {
           public static object GetWatermark(DependencyObject obj)
           {
               return (object)obj.GetValue(WatermarkProperty);
           }
     
           public static void SetWatermark(DependencyObject obj, object value)
           {
               obj.SetValue(WatermarkProperty, value);
           }
     
           // Using a DependencyProperty as the backing store for Watermark.  This enables animation, styling, binding, etc...
           public static readonly DependencyProperty WatermarkProperty =
               DependencyProperty.RegisterAttached("Watermark", typeof(object), typeof(DatePickerHelper),
                   new FrameworkPropertyMetadata(null,
                       new PropertyChangedCallback(OnWatermarkChanged)));
     
           private static void OnWatermarkChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
           {
               var datePicker = d as DatePicker;
               if (datePicker == null)
                   return;
               if (datePicker.IsLoaded)
               {
                   SetWatermarkInternal(datePicker, e.NewValue);
               }
               else
               {
                   RoutedEventHandler loadedHandler = null;
                   loadedHandler = delegate
                   {
                       datePicker.Loaded -= loadedHandler;
                       SetWatermarkInternal(datePicker, e.NewValue);
                   };
                   datePicker.Loaded += loadedHandler;
               }
           }
           private static void SetWatermarkInternal(DatePicker d, object value)
           {
               var textBox = d.Template.FindName("PART_TextBox", d) as Control;
               if (textBox != null)
               {
                   var watermarkControl = textBox.Template.FindName("PART_Watermark", textBox) as ContentControl;
                   if (watermarkControl != null)
                       watermarkControl.Content = value;
               }
           }
       }
    Thanks.


    • Edited by zleug Friday, October 31, 2014 3:27 PM
    Friday, October 31, 2014 3:26 PM

Answers

  • Hi,

    I have slightly Modified the code. Refer the below code. I have removed the shared variable for holding the string which was causing the issue.

    Public Class DatePickerHelper
        Dim datePicker As DatePicker
        Public Shared Function GetWatermark(obj As DependencyObject) As Object
            Return DirectCast(obj.GetValue(WatermarkProperty), Object)
        End Function
    
        Public Shared Sub SetWatermark(obj As DependencyObject, value As Object)
            obj.SetValue(WatermarkProperty, value)
        End Sub
    
        ' Using a DependencyProperty as the backing store for Watermark.  This enables animation, styling, binding, etc...
        Public Shared ReadOnly WatermarkProperty As DependencyProperty = DependencyProperty.RegisterAttached("Watermark", GetType(Object), GetType(DatePickerHelper),
                                                                                                             New FrameworkPropertyMetadata(Nothing, New PropertyChangedCallback(AddressOf OnWatermarkChanged)))
    
    
        Private Shared Sub OnWatermarkChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
            Dim datePicker = TryCast(d, DatePicker)
    
            If datePicker Is Nothing Then
                Return
            End If
    
            If datePicker.IsLoaded Then
                SetWatermarkInternal(datePicker, e.NewValue)
            Else
                AddHandler datePicker.Loaded, AddressOf loadedHandler
                datePicker.Tag = e.NewValue.ToString
            End If
    
        End Sub
    
        Private Shared Sub loadedHandler(ByVal sender As Object, ByVal e As RoutedEventArgs)
            Dim datePicker = TryCast(sender, DatePicker)
    
            RemoveHandler datePicker.Loaded, AddressOf loadedHandler
            SetWatermarkInternal(datePicker, datePicker.Tag)
        End Sub
        Private Shared Sub SetWatermarkInternal(d As DatePicker, value As Object)
            Dim textBox = TryCast(d.Template.FindName("PART_TextBox", d), Control)
            If textBox IsNot Nothing Then
                Dim watermarkControl = TryCast(textBox.Template.FindName("PART_Watermark", textBox), ContentControl)
                If watermarkControl IsNot Nothing Then
                    watermarkControl.Content = value
                End If
            End If
        End Sub
    End Class

    • Proposed as answer by Magnus (MM8)MVP Tuesday, November 4, 2014 9:23 AM
    • Marked as answer by zleug Wednesday, November 5, 2014 2:15 PM
    Monday, November 3, 2014 10:14 PM

All replies

  • Since you didn't tell us what the problem is:

    Private Shared Sub SetWatermarkInternal(d As DatePicker, value As Object)
    	Dim textBox = TryCast(d.Template.FindName("PART_TextBox", d), Control)
    	If textBox IsNot Nothing Then
    		Dim watermarkControl = TryCast(textBox.Template.FindName("PART_Watermark", textBox), ContentControl)
    		If watermarkControl IsNot Nothing Then
    			watermarkControl.Content = value
    		End If
    	End If
    End Sub


    Lloyd Sheen

    Friday, October 31, 2014 3:49 PM
  • Hi Lloyd. Thanks for replay.

    I have problem with:

     private static void OnWatermarkChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
           {
               var datePicker = d as DatePicker;
               if (datePicker == null)
                   return;
               if (datePicker.IsLoaded)
               {
                   SetWatermarkInternal(datePicker, e.NewValue);
               }
               else
               {
                   RoutedEventHandler loadedHandler = null;
                   loadedHandler = delegate
                   {
                       datePicker.Loaded -= loadedHandler;
                       SetWatermarkInternal(datePicker, e.NewValue);
                   };
                   datePicker.Loaded += loadedHandler;
               }
           }
    Thanks.
    • Edited by zleug Friday, October 31, 2014 4:02 PM
    Friday, October 31, 2014 4:02 PM
  • If you don't tell us what the problem is (second time asking) it will very difficult to help.

    Private Shared Sub OnWatermarkChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
    	Dim datePicker = TryCast(d, DatePicker)
    	If datePicker Is Nothing Then
    		Return
    	End If
    	If datePicker.IsLoaded Then
    		SetWatermarkInternal(datePicker, e.NewValue)
    	Else
    		Dim loadedHandler As RoutedEventHandler = Nothing
    		loadedHandler = Sub() 
    		datePicker.Loaded -= loadedHandler
    		SetWatermarkInternal(datePicker, e.NewValue)
    
    End Sub
    		datePicker.Loaded += loadedHandler
    	End If
    End Sub


    Lloyd Sheen


    • Edited by sqlguy Friday, October 31, 2014 4:08 PM
    Friday, October 31, 2014 4:07 PM
  • Same result I got when converted online. The lines:

    datePicker.Loaded -= loadedHandler

    datePicker.Loaded += loadedHandler

    have same error message:

    Public Event Loaded(sender As Object, e As System.Windows.RoutedEventArgs)' is an event, and cannot be called directly. Use a 'RaiseEvent' statement to raise an event.

    Friday, October 31, 2014 4:27 PM
  • Here is how you hook up an event handler in VB.NET:

    AddHandler datePicker.Loaded, AddressOf loadedHandler


    ...and this is how you remove it.

    RemoveHandler datePicker.Loaded, AddressOf loadedHandler
    

    Please remember to mark helpful posts as answer and/or helpful.

    Also, please ask VB.NET questions in the VB.NET forum: https://social.msdn.microsoft.com/Forums/vstudio/en-US/home?forum=vbgeneral

    Friday, October 31, 2014 4:35 PM
  • Sorry didn't check it.  

    Those lines are to add a handler and remove a handler.  The syntax for them is :

    AddHandler datePicker.Loaded,addressof(loadedHandler)

    and

    RemoveHandler datePicker.Loaded,addressof(loadedHandler)


    Lloyd Sheen

    Friday, October 31, 2014 4:35 PM
  • Next time for similar problem I will ask questions in VB.NET forum. I get same error message for lines like you suggested in previous post:

    'AddressOf' operand must be the name of a method (without parentheses).

    Friday, October 31, 2014 4:49 PM
  • same error message
    Friday, October 31, 2014 4:51 PM
  • You could define the event handler outside of OnWatermarkChanged:

        Dim datePicker As DatePicker
        Private Shared Sub OnWatermarkChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
            datePicker = TryCast(d, DatePicker)
            If datePicker Is Nothing Then
                Return
            End If
            If datePicker.IsLoaded Then
                SetWatermarkInternal(datePicker, e.NewValue)
            Else
                AddHandler datePicker.Loaded, AddressOf loadedHandler
            End If
        End Sub
    
        Private Shared Sub loadedHandler(ByVal sender As Object, ByVal e As RoutedEventArgs)
            RemoveHandler datePicker.Loaded, AddressOf loadedHandler
             SetWatermarkInternal(datePicker, e.NewValue);
        End Sub
    
    Please remember to mark helpful posts as answer and/or helpful.
    Friday, October 31, 2014 5:22 PM
  • Insert you code by this way:

        Private Shared Sub OnWatermarkChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
            Dim datePicker = TryCast(d, DatePicker)
    
            If datePicker Is Nothing Then
                Return
            End If
    
            If datePicker.IsLoaded Then
                SetWatermarkInternal(datePicker, e.NewValue)
            Else
                AddHandler datePicker.Loaded, AddressOf loadedHandler
            End If
    
        End Sub
    
        Private Shared Sub loadedHandler(d As DependencyObject, ByVal sender As Object, ByVal e As DependencyPropertyChangedEventArgs)
            Dim datePicker = TryCast(d, DatePicker)
    
            RemoveHandler datePicker.Loaded, AddressOf loadedHandler
            SetWatermarkInternal(datePicker, e.NewValue)
        End Sub

    And got other error message for same line point to loadedHandler:

    Method 'Private Shared Sub loadedHandler(d As System.Windows.DependencyObject, sender As Object, e As System.Windows.DependencyPropertyChangedEventArgs)' does not have a signature compatible with delegate 'Delegate Sub RoutedEventHandler(sender As Object, e As System.Windows.RoutedEventArgs)'.



    Friday, October 31, 2014 6:58 PM
  • Hi,

    Loaded event will not take the parameters which your are trying to define. So i modified the code. Please refer below code. I have added a shared variable for storing the string and adding it to the watermark on loaded event.

    Public Class DatePickerHelper
        Dim datePicker As DatePicker
        Shared newValue As String
        Public Shared Function GetWatermark(obj As DependencyObject) As Object
            Return DirectCast(obj.GetValue(WatermarkProperty), Object)
        End Function
    
        Public Shared Sub SetWatermark(obj As DependencyObject, value As Object)
            obj.SetValue(WatermarkProperty, value)
        End Sub
    
        ' Using a DependencyProperty as the backing store for Watermark.  This enables animation, styling, binding, etc...
        Public Shared ReadOnly WatermarkProperty As DependencyProperty = DependencyProperty.RegisterAttached("Watermark", GetType(Object), GetType(DatePickerHelper),
                                                                                                             New FrameworkPropertyMetadata(Nothing, New PropertyChangedCallback(AddressOf OnWatermarkChanged)))
    
    
        Private Shared Sub OnWatermarkChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
            Dim datePicker = TryCast(d, DatePicker)
    
            If datePicker Is Nothing Then
                Return
            End If
    
            If datePicker.IsLoaded Then
                SetWatermarkInternal(datePicker, e.NewValue)
            Else
                AddHandler datePicker.Loaded, AddressOf loadedHandler
                newValue = e.NewValue.ToString
            End If
    
        End Sub
    
        Private Shared Sub loadedHandler(ByVal sender As Object, ByVal e As RoutedEventArgs)
            Dim datePicker = TryCast(sender, DatePicker)
    
            RemoveHandler datePicker.Loaded, AddressOf loadedHandler
            SetWatermarkInternal(datePicker, newValue)
        End Sub
        Private Shared Sub SetWatermarkInternal(d As DatePicker, value As Object)
            Dim textBox = TryCast(d.Template.FindName("PART_TextBox", d), Control)
            If textBox IsNot Nothing Then
                Dim watermarkControl = TryCast(textBox.Template.FindName("PART_Watermark", textBox), ContentControl)
                If watermarkControl IsNot Nothing Then
                    watermarkControl.Content = value
                End If
            End If
        End Sub
    End Class


    Friday, October 31, 2014 9:15 PM
  • Hi AyyappanSubramanian. Thanks for replay.

    Great job. Thanks. Just one problem. I have two DatePicker controls. I specified them like:

    <DatePicker local:DatePickerHelper.Watermark="Start Date" />
    <DatePicker local:DatePickerHelper.Watermark="End Date" />

    When I run the form for both control I get End Date watermark. What is a problem and how it fix?

    Thanks.

    Monday, November 3, 2014 7:33 PM
  • Hi,

    I have slightly Modified the code. Refer the below code. I have removed the shared variable for holding the string which was causing the issue.

    Public Class DatePickerHelper
        Dim datePicker As DatePicker
        Public Shared Function GetWatermark(obj As DependencyObject) As Object
            Return DirectCast(obj.GetValue(WatermarkProperty), Object)
        End Function
    
        Public Shared Sub SetWatermark(obj As DependencyObject, value As Object)
            obj.SetValue(WatermarkProperty, value)
        End Sub
    
        ' Using a DependencyProperty as the backing store for Watermark.  This enables animation, styling, binding, etc...
        Public Shared ReadOnly WatermarkProperty As DependencyProperty = DependencyProperty.RegisterAttached("Watermark", GetType(Object), GetType(DatePickerHelper),
                                                                                                             New FrameworkPropertyMetadata(Nothing, New PropertyChangedCallback(AddressOf OnWatermarkChanged)))
    
    
        Private Shared Sub OnWatermarkChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
            Dim datePicker = TryCast(d, DatePicker)
    
            If datePicker Is Nothing Then
                Return
            End If
    
            If datePicker.IsLoaded Then
                SetWatermarkInternal(datePicker, e.NewValue)
            Else
                AddHandler datePicker.Loaded, AddressOf loadedHandler
                datePicker.Tag = e.NewValue.ToString
            End If
    
        End Sub
    
        Private Shared Sub loadedHandler(ByVal sender As Object, ByVal e As RoutedEventArgs)
            Dim datePicker = TryCast(sender, DatePicker)
    
            RemoveHandler datePicker.Loaded, AddressOf loadedHandler
            SetWatermarkInternal(datePicker, datePicker.Tag)
        End Sub
        Private Shared Sub SetWatermarkInternal(d As DatePicker, value As Object)
            Dim textBox = TryCast(d.Template.FindName("PART_TextBox", d), Control)
            If textBox IsNot Nothing Then
                Dim watermarkControl = TryCast(textBox.Template.FindName("PART_Watermark", textBox), ContentControl)
                If watermarkControl IsNot Nothing Then
                    watermarkControl.Content = value
                End If
            End If
        End Sub
    End Class

    • Proposed as answer by Magnus (MM8)MVP Tuesday, November 4, 2014 9:23 AM
    • Marked as answer by zleug Wednesday, November 5, 2014 2:15 PM
    Monday, November 3, 2014 10:14 PM
  • Hi AyyappanSubramanian. Thanks a lot.

    It is working great. I appreciate for your help.

    Wednesday, November 5, 2014 2:15 PM