Wal*_*lly 4 data-binding wpf f#
假设我有一个业务对象(没有AllowNullLiteralAttribute).
type Person(name: string) =
member val Name = name
override x.ToString() = name
Run Code Online (Sandbox Code Playgroud)
和视图模型,可选择设置所选人员.
type MainWindowModel() =
let mutable selectedPerson: Person option = None
:
member val People = ObservableCollection<Person>()
member x.SelectedPerson
with get() = selectedPerson
and set(v) =
if selectedPerson <> v then
selectedPerson <- v
x.RaisePropertyChanged("SelectedPerson")
Run Code Online (Sandbox Code Playgroud)
将WPF控件的SelectedItem属性绑定到F#选项属性(不使用AllowNullLiteralAttribute)的最佳方法是什么?
如果我这样做......
<StackPanel>
<ListBox ItemsSource="{Binding People}"
SelectedItem="{Binding SelectedPerson}"
DisplayMemberPath="Name" />
<TextBlock Text="{Binding SelectedPerson}" />
</StackPanel>
Run Code Online (Sandbox Code Playgroud)
...导致错误,无法将'George'从类型'Person'转换为'Microsoft.FSharp.Core.FSharpOption`1 [Person]'
我目前采取的方法是写我自己的方法IValueConverter.
open System
open System.Globalization
open System.Windows.Data
type OptionsTypeConverter() =
// from http://stackoverflow.com/questions/6289761
let (|SomeObj|_|) =
let ty = typedefof<option<_>>
fun (a:obj) ->
let aty = a.GetType()
let v = aty.GetProperty("Value")
if aty.IsGenericType && aty.GetGenericTypeDefinition() = ty then
if a = null then None
else Some(v.GetValue(a, [| |]))
else None
interface IValueConverter with
member x.Convert(value: obj, targetType: Type, parameter: obj, culture: CultureInfo) =
match value with
| null -> null
| SomeObj(v) -> v
| _ -> value
member x.ConvertBack(value: obj, targetType: Type, parameter: obj, culture: CultureInfo) =
match value with
| null -> None :> obj
| x -> Activator.CreateInstance(targetType, [| x |])
Run Code Online (Sandbox Code Playgroud)
然后我的XAML看起来像这样:
<StackPanel>
<ListBox ItemsSource="{Binding People}"
SelectedItem="{Binding SelectedPerson, Converter={StaticResource OptionsTypeConverter1}}"
DisplayMemberPath="Name" />
<TextBlock Text="{Binding SelectedPerson, Converter={StaticResource OptionsTypeConverter1}}" />
</StackPanel>
Run Code Online (Sandbox Code Playgroud)
可能有一种更简单的方法.该转换器可能已经存在于框架中.那里可能有更好的实现.
| 归档时间: |
|
| 查看次数: |
806 次 |
| 最近记录: |