如何将属性数据绑定到方法并传入参数

本文关键字:参数 方法 属性 数据绑定 | 更新日期: 2023-09-27 18:00:37

我有一个网格,在xaml中的每个单元格中都有一个矩形。我知道我可以将每个矩形的填充绑定到我的ViewModel中的一个属性,但我想将每个矩形填充绑定到ViewModel中一个方法,并传入矩形的x和y坐标,然后返回填充(在运行时可能会更改)。

有简单的方法吗?我不知道这是否可能,因为当该方法更改它为特定的x和y坐标返回的填充时,视图怎么会知道该方法更新了该值?

我面临的问题是,由于ViewModel不知道View上的任何UI控件,我不能直接更改矩形上的填充颜色。此外,由于网格可能很大,我不能为每个矩形都有一个单独的属性。

如何将属性数据绑定到方法并传入参数

这可能在您的场景中不起作用,但您可以使用ObjectDataProvider从绑定中调用方法。这里有一个快速的例子:

<Window.Resources>
  <local:StringToDoubleConverter x:Key="stringToDouble" />
  <local:MyObject x:Key="objInstance" />
  <ObjectDataProvider
    x:Key="odp"
    ObjectInstance="{StaticResource objInstance}"
    ObjectMethod="MyMethod"
    >
    <ObjectDataProvider.MethodParameters>
      <sys:Double>0</sys:Double>
    </ObjectDataProvider.MethodParameters>
  </ObjectDataProvider>
</Window.Resources>

现在,您视图中的一个元素,比如TextBox,可以绑定到方法参数:

<TextBox Text={Binding Source={StaticResource odp}, Path=MethodParameters[0], UpdateSourceTrigger=PropertyChanged, Converter={StaticResource stringToDouble}} />

方法返回值可以在其他地方的绑定中使用:

<Label Content="{Binding Source={StaticResource odp}}" ContentStringFormat="Method returned: {0}" />

同样,这可能在您的场景中不起作用,但它确实说明了一种将参数传递给方法并完全在XAML中使用返回值的方法。以下是获取更多信息的资源:http://bea.stollnitz.com/blog/?p=22

绑定不能用作调用方法和传递参数的方法。它只是一种在视图和视图模型之间同步状态的机制。

在您的情况下,视图模型需要知道矩形的坐标才能确定填充。因此,对于每个矩形,视图模型都需要公开X, Y, Fill属性。

这里的大问题是如何为视图模型提供X&Y坐标?我猜这些矩形是在某种容器中,它决定了它们的位置?如果是这样的话,我能想到的唯一技术就是为UIElement创建一个附加行为,该行为通过TransformToVisual计算其位置。参见示例:

http://forums.silverlight.net/forums/p/12160/414862.aspx

然后可以将其绑定到您的X&视图模型中的Y值。

然而,老实说,如果你很难让MVVM在这里工作,也许这是错误的模式?

如果你只是在构建一个由彩色矩形组成的UI,我只会在一个循环中完成,添加矩形并在代码后面为它们着色!

KISS(保持简单愚蠢!)

您可以尝试使用IValueConverter进行以下操作:

[ValueConversion(typeof (MyCoordObject), typeof (Brush))]
public class CoordToBrushConverter : ConverterExtension
{
   public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var coordObject= (MyCoordObject) value;
        if (coordObject.X == 132) return Brushes.Red; 
        //define your own brushes as StaticResource or something, this won't work
        return Brushes.Black;
    }

    public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        //nothing
        return value;
    }
}

现在你只需要弄清楚你想把哪个对象传递给转换器。在XAML中这样使用:

<my:CoordToBrushConverter x:key="myConverter"/>
<TextBox BackgroundBrush={Binding myObj, Converter={StaticResource myConverter}} />

如果您没有包含到坐标的对象,也许您可以使用MultiValueConverter并从控件中逐个传递坐标?你应该玩这个,也许能让它发挥作用。

如果你不想使用转换器,你可以随时查看一些MVVM框架,如果我没有弄错的话,其中一些框架支持绑定到方法
检查Caliburn或MVVMLight

HTH