Get Background Color for a control

Aug 13, 2010 at 12:11 PM
Edited Aug 13, 2010 at 12:15 PM

Hello everyone!

This project rocks - let me get that out of my system... Found just in time...

I want to get hold of the background color of a textbox (that I've set with the following line:mytextBox.Background = Brushes.Red).

Is that possible?

I read something (here: http://white.codeplex.com/Thread/View.aspx?ThreadId=55843) about a strange workaround that involved a screen shot and parsing the image (described here: http://social.msdn.microsoft.com/Forums/en-US/windowsaccessibilityandautomation/thread/b9c29725-842a-40a6-8095-215d95250bbc)...

Brrr - don't wanna go there. Hopefully there is another way? Please?

I'm using White 0.20 and testing a WPF-application written with Prism

/Marcus

Coordinator
Aug 15, 2010 at 6:19 AM

have a look at CustomCommands

Aug 16, 2010 at 9:15 AM

Hello and thanks for a quick answer.

I have some troubles though. Here is my implementation, which follows your example closely (i hope):

Imports System.Windows.Media
Imports System.Windows.Controls
Imports System.Runtime.Serialization


Public Interface IBackgroundColor
    ReadOnly Property BackgroundColor As BackgroundColor
End Interface

Public Class TextBoxCommands
    Implements IBackgroundColor

    Private ReadOnly _textbox As TextBox

    Public Sub New(ByVal txtBox As TextBox)
        _textbox = txtBox
    End Sub

    Public ReadOnly Property BackgroundColor As BackgroundColor Implements IBackgroundColor.BackgroundColor
        Get
            Return New BackgroundColor(_textbox.Background)
        End Get
    End Property
End Class

<DataContract()> _
Public Class BackgroundColor

    <DataMember()> _
    Private ReadOnly _color As Color

    Public Sub New(ByVal color As Windows.Media.Brush)
        _color = DirectCast(color, SolidColorBrush).Color
    End Sub

    Public ReadOnly Property Color As Windows.Media.Color
        Get
            Return _color
        End Get
    End Property

End Class

    <Test>
    Public Sub TextBoxShouldHaveBackgroundColor(ByVal wellKnownTextBoxName As String, ByVal colorName As String)
        CustomCommandSerializer.AddKnownTypes(GetType(BackgroundColor))

        Dim textBox = _calculatorWindow.Get(Of TextBox)(ConvertWellKnownNameToID(wellKnownTextBoxName))

        Dim wpfWhiteTextBox = New CustomCommandFactory().Create(Of IBackgroundColor)(textBox)

        Dim actualBackGroundColor = wpfWhiteTextBox.BackgroundColor

        Dim expectedColor = System.Windows.Media.ColorConverter.ConvertFromString(colorName)

        Assert.AreEqual(expectedColor, actualBackGroundColor)

    End Sub

OK - when I run this I get an exception on the row where I read the BackgroundColor property (Dim actualBackGroundColor = wpfWhiteTextBox.BackgroundColor). The exception simply states "White.Core.WhiteException: Exception when executing command. Exception Details: Marcusoft.BDD.Calculator.Specs.dll".

Any suggestions? I use White 0.20 (latest download)

/Marcus

Coordinator
Aug 16, 2010 at 10:10 AM

Can you please provide complete stacktrace of exception.

Also, have you used WhiteTextBox in your application under test?

Aug 16, 2010 at 10:28 AM

Eeeh WhiteTextBox?

I have a created a WPF-application and used standard controls there (<TextBox> in XAML).

Does White require me to use the White-controls? I didn't catch that.

Aug 16, 2010 at 10:41 AM

For what's it worth (supect that you will have something to say about not using the WhiteTextBox...), here is the stack trace:

   at White.Core.CustomCommands.CustomCommandInterceptor.Intercept(IInvocation invocation)
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at IBackgroundColorProxy817312d6bfb848cfb957b23dbc067182.get_BackgroundColor()
   at Marcusoft.BDD.Calculator.Specs.CalculatorSteps.TextBoxShouldHaveBackgroundColor(String wellKnownTextBoxName, String colorName) in c:\dev\Marcusoft.BDD.Calculator\Marcusoft.BDD.Calculator.Specs\Steps\CalculatorSteps.vb:line 91
   at lambda_method(Closure , String , String )

 

Hope you can make something out of that

/Marcus

Aug 18, 2010 at 8:17 AM
@viveksingh - is it possible for me to get hold of the code of the exampel you have on CustomCommands? I'll take it from there
Aug 18, 2010 at 8:51 AM

OK, I have now tried to implement your example from http://white.codeplex.com/wikipage?title=Custom%20Commands&referringTitle=Home

That gave me the following error "(NULL) does not implement ValuePattern".

What am I missing?

Where should I use the WhiteTextBox? In my XAML, in the Command-class (ButtonCommands, TextBoxCommands)?

I don't get this... Sorry

/Marcus

Coordinator
Aug 22, 2010 at 3:48 AM

Looks like the UIItem on which you are issuing the command has automation element = null. This is possible if the search criteria didn't find anything.

Aug 22, 2010 at 8:30 AM
Hmmm - i have an eeire feeling this will end up embarissing for me ;) I was trying to replicate your example with BorderThickness. Any possiblity to get the code for that? Thanks for helping me.
Aug 31, 2010 at 12:33 PM

I have had some progress in this matter, but I'm still stumped with another exception.

Here is my xaml: 

        <CustomControls:WhiteTextBox Height="23" HorizontalAlignment="Left" Margin="115,12,0,0" Name="number1" VerticalAlignment="Top" Width="75" Background="White" />

And then I implemented the TextBoxCommands from your ButtonCommands template as follows:

Imports System.Windows.Media
Imports System.Windows.Controls
Imports System.Runtime.Serialization
Imports White.CustomControls


Public Interface ITextBoxCommands
    ReadOnly Property BackgroundBrush() As BackgroundBrush
End Interface

Public Class TextBoxCommands
    Implements ITextBoxCommands

    Private ReadOnly _textbox As Windows.Controls.TextBox

    Public Sub New(ByVal txtBox As Windows.Controls.TextBox)
        _textbox = txtBox
    End Sub

    Public ReadOnly Property BackgroundBrush As BackgroundBrush Implements ITextBoxCommands.BackgroundBrush
        Get
            Return New BackgroundBrush(_textbox.Background)
        End Get
    End Property
End Class

<DataContract()> _
Public Class BackgroundBrush

    <DataMember()> _
    Private ReadOnly _brush As Windows.Media.Brush

    Public Sub New(ByVal color As Windows.Media.Brush)
        _brush = color
    End Sub

    Public ReadOnly Property Brush As Windows.Media.Brush
        Get
            Return _brush
        End Get
    End Property

End Class

Finally I have the following test-code to get the background brush for the button:

CustomCommandSerializer.AddKnownTypes(GetType(BackgroundBrush))
Dim textbox = GetControlByName(Of TextBox)(wellKnownTextBoxName)
Dim wpfTextBox = New CustomCommandFactory().Create(Of ITextBoxCommands)(textbox)
Dim color = wpfTextBox.BackgroundBrush

And it fails on the row: Dim color = wpfTextBox.BackgroundBrush with the following exception:

Error in line 1 position 197. Expecting element 'ArrayOfanyType' from namespace 'http://schemas.microsoft.com/2003/10/Serialization/Arrays'.. 
Encountered 'Element'  with name 'SerializationException', namespace 'http://schemas.datacontract.org/2004/07/System.Runtime.Serialization'. 

And stack-trace:

   at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
   at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
   at System.Runtime.Serialization.XmlObjectSerializer.ReadObject(XmlDictionaryReader reader)
   at System.Runtime.Serialization.XmlObjectSerializer.ReadObject(Stream stream)
   at Bricks.Objects.BricksDataContractSerializer.ToObject[T](String string, IEnumerable`1 knownTypes)
   at White.Core.CustomCommands.CustomCommandSerializer.ToObject(String string)
   at White.Core.UIItems.UIItem.Execute(ValuePattern valuePattern, String assemblyFile, String typeName, MethodInfo method, Object[] arguments)
   at White.Core.UIItems.UIItem.Do(String assemblyFile, String typeName, MethodInfo method, Object[] arguments)
   at White.Core.CustomCommands.CustomCommandInterceptor.Intercept(IInvocation invocation)
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at ITextBoxCommandsProxy48959ef6cfd342d3bb406ccb11730e6e.get_BackgroundColorBrush()
   at Marcusoft.BDD.Calculator.Specs.CalculatorSteps.TextBoxShouldHaveBackgroundColor(String wellKnownTextBoxName, String colorName) in c:\dev\Marcusoft.BDD.Calculator\Marcusoft.BDD.Calculator.Specs\Steps\CalculatorSteps.vb:line 107
   at lambda_method(Closure , String , String )

So - what am I doing wrong?

Can someone help me out here?

/Marcus

Coordinator
Sep 2, 2010 at 10:19 AM

you are using windows.media.brush which is not a serializable object. you have extract out essential values from it in the command and return that.

Sep 2, 2010 at 11:03 AM
OK - that explains the strange error message... 

I have now changed my code to return the name of the color (since I wasn't to sure if Color is serilizable). So here is my new TextBoxCommand-class

Imports System.Windows.Media
Imports System.Windows.Controls
Imports System.Runtime.Serialization
Imports White.CustomControls


Public Interface ITextBoxCommands
    ReadOnly Property BackgroundSolidColor() As BackgroundSolidColor
End Interface

Public Class TextBoxCommands
    Implements ITextBoxCommands

    Private ReadOnly _textbox As Windows.Controls.TextBox

    Public Sub New(ByVal txtBox As Windows.Controls.TextBox)
        _textbox = txtBox
    End Sub

    Public ReadOnly Property BackgroundBrush As BackgroundSolidColor Implements ITextBoxCommands.BackgroundSolidColor
        Get
            Dim brush = _textbox.Background
            Return New BackgroundSolidColor(DirectCast(brush, SolidColorBrush).Color.ToString())
        End Get
    End Property
End Class

<DataContract()> _
Public Class BackgroundSolidColor

    <DataMember()> _
    Private ReadOnly _solidColor As String

    Public Sub New(ByVal color As String)
        _solidColor = color
    End Sub

    Public ReadOnly Property ColorName As String
        Get
            Return _solidColor
        End Get
    End Property

End Class

But now I fail on the same row (accessing the ColorName this time wpfTextBox.BackgroundSolidColor.ColorName) with the following exception:

Test method Marcusoft.BDD.Calculator.Specs.Marcusoft.BDD.Calculator.Specs.ShouldNotPerformCalculationsWithNegativeNumbersFeature.WritingNegativeNumberAsNumber1 threw exception: 
White.Core.WhiteException: Exception when executing command. Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
   at White.CustomControls.Peers.Automation.CustomCommand.Execute(Object control)
   at White.CustomControls.Peers.Automation.WhitePeer.SetValue(String commandString)

And stack trace

   at White.Core.CustomCommands.CustomCommandInterceptor.Intercept(IInvocation invocation)
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at ITextBoxCommandsProxye3dddca923284258a987fcce28bdcafb.get_BackgroundSolidColor()
   at Marcusoft.BDD.Calculator.Specs.CalculatorSteps.TextBoxShouldHaveBackgroundColor(String wellKnownTextBoxName, String colorName) in c:\dev\Marcusoft.BDD.Calculator\Marcusoft.BDD.Calculator.Specs\Steps\CalculatorSteps.vb:line 102
   at lambda_method(Closure , String , String )

Are I'm getting closer? Not sure myself...