从XAML访问C#的函数



我的XAML代码-中有这个按钮

           <Button x:Name="button" 
            Content="{Binding Name}" 
            Click="Start"  
            HorizontalAlignment="Left" 
            Margin="123,45,0,0" 
            VerticalAlignment="Top"/>

我有另一个C#代码-

namespace MyGame
{
    public sealed partial class MainPage : Page
    {
        public string Name()
          {
             get{ return "Hello" };
          }
       private void ButtonNo3(object sender, RoutedEventArgs e)
        {
          Button obj = (Button)sender;
          var selectedButton = obj.Content.ToString();
          //This is where I get this error-An exception of type        'System.NullReferenceException' occurred in MyGame.exe but was not handled in user code
         }
    }
  }

我的问题是,如何在xaml代码中获得ButtonContent,以存储C#代码函数的值?

您可以通过绑定来实现这一点。绑定有几个规则:

  • 您只能绑定到属性
  • 这些属性必须是公共的
  • 要计算绑定,该属性必须位于视图的DataContext

该数据上下文通常是ViewModel对象,而不是视图本身,遵循MVVM模式。

因此,在你的视图模型中,你会有:

//Properties (and methods) are PascalCase!
public string Name { get { return "Hello";} }

一旦设置了数据上下文,XAML就是:

      <Button x:Name="button" 
        Content="{Binding Name}" 
        Click="Start"  
        HorizontalAlignment="Left" 
        Margin="123,45,0,0" 
        VerticalAlignment="Top"/>

由于您没有提到同步的必要性,因此问题的最简单答案是使用x:Name标识符,并通过C#代码中的函数设置内容属性。

button.Content = name();

如果您可以将方法移动到另一个类中,还可以使用ObjectDataProvider将方法name连接到XAML代码,然后使用数据绑定将数据提供程序连接到代码:

<Grid>
    <Grid.Resources>
        <ObjectDataProvider x:Key="fnName"
                         ObjectType="{x:Type bind:SomeClassHoldingYourMethod}"
                         MethodName="name">
        </ObjectDataProvider>
    </Grid.Resources>
    <Button x:Name="button" 
        Content="{Binding Source={StaticResource fnName}, Mode=OneTime}" 
        HorizontalAlignment="Left" 
        Margin="123,45,0,0" 
        VerticalAlignment="Top"/>
</Grid>

但是,如果您想要一种更简单的方法,并且希望您的数据与UI同步(因此,每当您更改数据中的某些内容时,它都会自动反映在UI控件上),则可以将函数转换为只读属性,并按照@BradleyDotNET的建议执行。

通常,将数据绑定与实际数据分离被认为是一件好事。

请注意,在WPF中,您总是可以在XAML中以声明方式执行,但也可以使用C#在代码中以编程方式执行相同的操作。大多数人更喜欢声明式的方式,但如果你需要的话,最好知道你可以在C#中做同样的事情(甚至更多)

请使用.NET框架命名约定,并使用pascalCase命名方法。

如果您想从XAML访问方法,您的选项相对受到限制。

第一个也是最明显的是使用事件处理程序,它进入View的代码后面,从而违反MVVM。但是,可以提供执行代码的最简单方法。如果使用ViewModel,也可以使用dynamic执行到所需方法的后期绑定,但只能从C#代码执行。

<Button ...
        Clicked="Button_OnClick"/>

和后面的代码

public void Button_OnClick(object sender, RoutedEventArgs e)
{
    (DataContext as dynamic).ButtonClicked;
}

请注意,虽然可以使用特定类型的ViewModel而不是dynamic,但这也会违反MVVM模式,而且比代码隐藏更糟糕,因为它会强制您的View与特定的ViewModel一起使用。

另一个选项是使用InteractionsCallMethodAction(来自Expressions Blend SDK)。

<Button>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <ei:CallMethodAction MethodName="ButtonClicked"/>
        </i:EventTrigger>
    </i:InterAction.Triggers>
</Button>

最新更新