mirror of https://github.com/AMT-Cheif/Stylet.git
Turn s:ViewModel into a proper binding, making it vaguely useful
This commit is contained in:
parent
e8d9f95dfd
commit
7fe21eb40b
|
@ -131,7 +131,7 @@
|
|||
<Compile Include="Xaml\View.cs" />
|
||||
<Compile Include="ViewManager.cs" />
|
||||
<Compile Include="WindowManager.cs" />
|
||||
<Compile Include="Xaml\ViewModelExtension.cs" />
|
||||
<Compile Include="Xaml\ViewModelBindingExtension.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="MessageBoxView.xaml">
|
||||
|
|
|
@ -150,6 +150,15 @@ namespace Stylet.Xaml
|
|||
view.Resources[ViewModelProxyResourceKey] = bindingProxy;
|
||||
}
|
||||
|
||||
internal static void EnsureViewModelProxyValueSetUp(DependencyObject view)
|
||||
{
|
||||
if (view.GetValue(ViewModelProxyProperty) == null)
|
||||
{
|
||||
var resource = new DynamicResourceExtension(ViewModelProxyResourceKey).ProvideValue(null);
|
||||
view.SetValue(ViewModelProxyProperty, resource);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetch a binding which can be used to retrieve the ViewModel associated with a View
|
||||
/// </summary>
|
||||
|
@ -157,11 +166,7 @@ namespace Stylet.Xaml
|
|||
/// <returns>Binding which can retrieve the ViewModel</returns>
|
||||
public static Binding GetBindingToViewModel(DependencyObject view)
|
||||
{
|
||||
if (view.GetValue(ViewModelProxyProperty) == null)
|
||||
{
|
||||
var resource = new DynamicResourceExtension(ViewModelProxyResourceKey).ProvideValue(null);
|
||||
view.SetValue(ViewModelProxyProperty, resource);
|
||||
}
|
||||
EnsureViewModelProxyValueSetUp(view);
|
||||
|
||||
var binding = new Binding()
|
||||
{
|
||||
|
@ -174,7 +179,7 @@ namespace Stylet.Xaml
|
|||
return binding;
|
||||
}
|
||||
|
||||
private static readonly DependencyProperty ViewModelProxyProperty =
|
||||
internal static readonly DependencyProperty ViewModelProxyProperty =
|
||||
DependencyProperty.RegisterAttached("ViewModelProxy", typeof(BindingProxy), typeof(View), new PropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace Stylet.Xaml
|
||||
{
|
||||
/// <summary>
|
||||
/// MarkupExtension which can retrieve the ViewModel for the current View, if available
|
||||
/// </summary>
|
||||
public class ViewModelBindingExtension : MarkupExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the path to the property
|
||||
/// </summary>
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the converter to use.
|
||||
/// </summary>
|
||||
public IValueConverter Converter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the culture in which to evaluate the converter.
|
||||
/// </summary>
|
||||
public CultureInfo ConverterCulture { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parameter to pass to the Converter.
|
||||
/// </summary>
|
||||
public object ConverterParameter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value to use when the binding is unable to return a value
|
||||
/// </summary>
|
||||
public object FallbackValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a string that specifies how to format the binding if it displays the bound value as a string
|
||||
/// </summary>
|
||||
public string StringFormat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value that is used in the target when the value of the source is null
|
||||
/// </summary>
|
||||
public object TargetNullValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates a new instance of the <see cref="ViewModelBindingExtension"/> class
|
||||
/// </summary>
|
||||
public ViewModelBindingExtension()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the Binding class with an initial path
|
||||
/// </summary>
|
||||
/// <param name="path">The initial Path for the binding</param>
|
||||
public ViewModelBindingExtension(string path)
|
||||
{
|
||||
this.Path = path;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When implemented in a derived class, returns an object that is provided as the
|
||||
/// value of the target property for this markup extension.
|
||||
/// </summary>
|
||||
/// <param name="serviceProvider">A service provider helper that can provide services for the markup extension.</param>
|
||||
/// <returns>The object value to set on the property where the extension is applied.</returns>
|
||||
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||
{
|
||||
var valueService = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
|
||||
var targetObjectAsDependencyObject = valueService.TargetObject as DependencyObject;
|
||||
if (targetObjectAsDependencyObject == null)
|
||||
return this;
|
||||
|
||||
View.EnsureViewModelProxyValueSetUp(targetObjectAsDependencyObject);
|
||||
|
||||
var binding = new Binding()
|
||||
{
|
||||
Source = targetObjectAsDependencyObject,
|
||||
Path = new PropertyPath("(0).(1)." + this.Path, View.ViewModelProxyProperty, BindingProxy.DataProperty),
|
||||
Mode = BindingMode.OneWay,
|
||||
Converter = this.Converter,
|
||||
ConverterCulture = this.ConverterCulture,
|
||||
ConverterParameter = this.ConverterParameter,
|
||||
FallbackValue = this.FallbackValue,
|
||||
StringFormat = this.StringFormat,
|
||||
TargetNullValue = this.TargetNullValue,
|
||||
};
|
||||
|
||||
return binding.ProvideValue(serviceProvider);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace Stylet.Xaml
|
||||
{
|
||||
/// <summary>
|
||||
/// MarkupExtension which can retrieve the ViewModel for the current View, if available
|
||||
/// </summary>
|
||||
public class ViewModelExtension : MarkupExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// Instantiates a new instance of the <see cref="ViewModelExtension"/> class
|
||||
/// </summary>
|
||||
public ViewModelExtension()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When implemented in a derived class, returns an object that is provided as the
|
||||
/// value of the target property for this markup extension.
|
||||
/// </summary>
|
||||
/// <param name="serviceProvider">A service provider helper that can provide services for the markup extension.</param>
|
||||
/// <returns>The object value to set on the property where the extension is applied.</returns>
|
||||
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||
{
|
||||
var valueService = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
|
||||
var targetObjectAsDependencyObject = valueService.TargetObject as DependencyObject;
|
||||
if (targetObjectAsDependencyObject == null)
|
||||
return this;
|
||||
|
||||
return View.GetBindingToViewModel(targetObjectAsDependencyObject).ProvideValue(serviceProvider);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -51,7 +51,7 @@
|
|||
<GroupBox DockPanel.Dock="Top" Header="{}{ViewModel}" Padding="10">
|
||||
<DockPanel DataContext="{x:Null}">
|
||||
<TextBlock DockPanel.Dock="Top">Ensure that the label below displays the text "Pass":</TextBlock>
|
||||
<TextBlock DockPanel.Dock="Top" DataContext="{s:ViewModel}" Text="{Binding ViewModelTestLabel}"/>
|
||||
<TextBlock DockPanel.Dock="Top" Text="{s:ViewModelBinding ViewModelTestLabel}"/>
|
||||
</DockPanel>
|
||||
</GroupBox>
|
||||
</DockPanel>
|
||||
|
|
Loading…
Reference in New Issue