gpt4 book ai didi

c# - 如何将参数从 XAML 中定义的事件的 MarkupExtension 传递到 wpf 4.5 中模型中定义的方法

转载 作者:太空宇宙 更新时间:2023-11-03 13:49:15 24 4
gpt4 key购买 nike

我正在为我已经讨论过的按钮单击事件创建标记扩展 here .

我的下一个问题是如何将参数从 XAML 传递到 viewmodel 中的方法?

最佳答案

这是一个允许您传递参数的解决方案,您可以发送 DataContext 中的任何属性和 DataContext 中的 Controls 中的属性>

标记扩展

public class Call : MarkupExtension
{
public Call() { }

public string MethodName { get; set; }
public string Path { get; set; }
public string ElementName { get; set; }

public override object ProvideValue(IServiceProvider serviceProvider)
{
IProvideValueTarget targetProvider = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
if (targetProvider != null)
{
var target = targetProvider.TargetObject as FrameworkElement;
if (target != null)
{
if (targetProvider.TargetProperty is MethodInfo)
{
var targetEventAddMethod = targetProvider.TargetProperty as MethodInfo;
if (targetEventAddMethod != null)
{
var delegateType = targetEventAddMethod.GetParameters()[1].ParameterType;
var methodInfo = this.GetType().GetMethod("MyProxyHandler", BindingFlags.NonPublic | BindingFlags.Instance);
return Delegate.CreateDelegate(delegateType, this, methodInfo); ;
}
}
else if (targetProvider.TargetProperty is EventInfo)
{
var targetEventInfo = targetProvider.TargetProperty as EventInfo;
if (targetEventInfo != null)
{
var delegateType = targetEventInfo.EventHandlerType;
MethodInfo methodInfo = this.GetType().GetMethod("MyProxyHandler", BindingFlags.NonPublic | BindingFlags.Instance);
return Delegate.CreateDelegate(delegateType, this, methodInfo);
}
}
}
}
return null;
}

void MyProxyHandler(object sender, EventArgs e)
{
FrameworkElement target = sender as FrameworkElement;
if (target == null) return;
var dataContext = target.DataContext;
if (dataContext == null) return;

//get the method on the datacontext from its name
MethodInfo methodInfo = dataContext.GetType().GetMethod(MethodName, BindingFlags.Public | BindingFlags.Instance);
if (!string.IsNullOrEmpty(ElementName))
{
var element = FindVisualChildren(dataContext as DependencyObject).FirstOrDefault(c => c.Name.Equals(ElementName));
if (element != null)
{
var path = element.GetType().GetProperty(Path);
if (path != null)
{
methodInfo.Invoke(dataContext, new object[] { path.GetValue(element, null) });
}
return;
}
}

if (!string.IsNullOrEmpty(Path))
{
var path = dataContext.GetType().GetProperty(Path);
if (path != null)
{
methodInfo.Invoke(dataContext, new object[] { path.GetValue(dataContext, null) });
}
return;
}

methodInfo.Invoke(dataContext,null);
}

private IEnumerable<FrameworkElement> FindVisualChildren(DependencyObject obj)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is FrameworkElement)
{
yield return (FrameworkElement)child;
}
var childOfChild = FindVisualChildren(child);
if (childOfChild != null)
{
foreach (var subchild in childOfChild)
{
yield return subchild;
}
}
}
}
}

测试应用:

代码:

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private int myVar = 700;
public int MyProperty
{
get { return myVar; }
set { myVar = value; }
}

public void TestMethod1()
{

}

public void TestMethod2(int value)
{

}

public void TestMethod3(string value)
{

}
}

Xaml:

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication11"
xmlns:System="clr-namespace:System;assembly=mscorlib" x:Class="WpfApplication11.MainWindow"
Title="MainWindow" Height="123" Width="275" x:Name="UI"
>
<Grid DataContext="{Binding ElementName=UI}">
<StackPanel>
<TextBlock Name="txtblock" Text="Hello" />
<Button Click="{local:Call MethodName=TestMethod1}" Height="24"/>
<Button Click="{local:Call MethodName=TestMethod2, Path=MyProperty}" Height="24"/>
<Button Click="{local:Call MethodName=TestMethod3, ElementName=txtblock, Path=Text}" Height="24" />
</StackPanel>
</Grid>
</Window>

关于c# - 如何将参数从 XAML 中定义的事件的 MarkupExtension 传递到 wpf 4.5 中模型中定义的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14209616/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com