I have tried to create a "UserControl" "By-Code" only, using F# (Vers. 12.0.30815.0 + Framework 4.5) since I prefer this "way" (no mix between C# and F#).
NOTE: I have to show multiple properties of a single Class in an Input Form, so this UserControl need to implement Binding capabilities to connect the "output" to the Class's Properties.
I tried to modify the numeric values inside the window (i.e. 1200 or 400) or moving the focus between the controls using the TAB key located on the keyboard, but everiting seem locked.
No update of the numerical value can be achieved. I can only delete one or more single figures, without any updates.
Perhaphs there is a conceptual error inside the Event "dataChangedEvent" that I have implemented inside the UserControls (i.e. "Data" property of the "ucData" Control - see the Code). It is something like: "INotifyPropertyChanged".
NOTE: perhaphs this error in the implementation of the Event is also present with the "Description" and "UnitOfMeasure" Porperties of the UserControl.
Can somebody can hel me to discover where is/are my error/erros in the here below reported Lines of Codes?
many Thanks in advance.
ANN
DEFINE THE USER CONTROL
type ucData() as this =
inherit Windows.Controls.UserControl()
static let OnDataPropertyChanged (sender:DependencyObject) (e:DependencyPropertyChangedEventArgs) =
let control = unbox<ucData>(sender)
let newValue = unbox<double>(e.NewValue)
let oldValue = unbox<double>(e.OldValue)
System.Console.WriteLine
(sprintf
">>> OnPropertyChanged 'ucData':'Data': Control Name: %s; Value: %f --> %f <<<"
control.Name oldValue newValue )
let argsEvent = new RoutedPropertyChangedEventArgs<double>(oldValue, newValue)
argsEvent.RoutedEvent <- ucData.DataChangedEvent // I get an ERROR here!!!!
control.RaiseEvent(argsEvent)
static let OnCoerceDataProperty (sender:DependencyObject) (data:obj) =
let control = unbox<ucData>(sender)
let value = unbox<double>(data)
System.Console.WriteLine
(sprintf
">>> OnCoerceValue 'ucData':'Data': Control Name: %s; Value: : %f <<<"
control.Name value )
box(value)
static let OnValidateDataProperty (data:obj) =
System.Console.WriteLine
(sprintf
">>> OnValidateValue 'ucData':'Data': Data %s <<<"
(data.ToString()) )
data.GetType() = typeof<double>
static let dpData =
DependencyProperty.Register("Data",typeof<double>, typeof<ucData>,
new FrameworkPropertyMetadata( 0.0,
FrameworkPropertyMetadataOptions.Inherits,
new PropertyChangedCallback(OnDataPropertyChanged),
new CoerceValueCallback(OnCoerceDataProperty) ),
new ValidateValueCallback(OnValidateDataProperty) )
static let reDataChangedEvent =
EventManager.RegisterRoutedEvent
("DataChanged", RoutingStrategy.Bubble,
typeof<RoutedPropertyChangedEventHandler<double>>, typeof<ucData>)
let dataChangedEvent =
let e = new Event<RoutedPropertyChangedEventHandler<double>,RoutedPropertyChangedEventArgs<double>>()
// Equialent to:
// public event RoutedPropertyChangedEventHandler<double> DataChanged
// {
// add { AddHandler(DataChangedEvent, value); }
// remove { RemoveHandler(DataChangedEvent, value); }
// }
// where DataChangedEvent is so defined:
// public static readonly RoutedEvent DataChangedEvent;
e
let grid =
let c = new Grid()
let colData = new ColumnDefinition()
colData.MinWidth <- 70.
c.ColumnDefinitions.Add( colData )
c
let data=
let c = new TextBox()
c.Margin<- new Thickness(3.0)
c.SetValue(Grid.ColumnProperty,1)
c
do
grid.Children.Add(data) |> ignore
this.AddChild(grid) |> ignore
let bData = new Binding()
bData.Path <- new PropertyPath("Data")
bData.StringFormat <- "N"
bData.ConverterCulture <- System.Globalization.CultureInfo.InvariantCulture
bData.Mode <- BindingMode.TwoWay
bData.RelativeSource <- new RelativeSource(RelativeSourceMode.FindAncestor,typeof<ucData>,1)
data.SetBinding(TextBox.TextProperty, bData) |> ignore
static member DataProperty = dpData
[<Description("Specify the Numerical Data"); Category("UserData")>]
member x.Data
with get() =
let res = x.GetValue(ucData.DataProperty)
(res :?> double)
and set (v:double) =
x.SetValue(ucData.DataProperty, v )
[<CLIEvent>]
static member DataChangedEvent with get() = reDataChangedEvent // I get an ERROR here!!!
[<CLIEvent>]
member x.DataChanged = dataChangedEvent.Publish
CREATE THE WINDOW
type TestWindow() as this =
inherit Window()
let c1 = new ucData()
let c2 = new ucData()
do
c1.Name <- "Data1"
c2.Name <- "Data2"
this.Width <- 300.
this.Height <- 300.
let sp = new StackPanel()
c1.Data <- 1200.
c2.Data <- 400.
sp.Children.Add(c1) |> ignore
sp.Children.Add(c2) |> ignore
c1.DataChanged.Add( fun args ->
MessageBox.Show("The button labeled \"" + c1.Data.ToString()) |>ignore )
c2.DataChanged.Add( fun args ->
MessageBox.Show("The button labeled \"" + c1.Data.ToString()) |>ignore )
this.Content <- sp
RUN THE TEST WINDOW
let w = new TestWindow()
w.Show()