我敢肯定,这是一个荒谬可笑的问题,但是无论如何我都在问,因为我已经搜索了很多东西,或者不理解我所看到的解决方案,或者找不到我想要的答案。

我有一个MVVM应用程序。我的XAML是在DataContext设置为VM的情况下设置的,其中从VM的属性填充屏幕上的数据项。我的CodeBehind不会摆弄数据,只会摆弄与屏幕有关的东西。

我现在想做的是将某些UI元素绑定(bind)到foo.xaml.cs(CodeBehind)文件中的属性。例如,我想指定FontSize绑定(bind)到CB中的属性,以便在CB的WindowInitialized处理程序中,它可以检测屏幕大小并更改将所有屏幕项目的FontSize =绑定(bind)到的一个变量。

我可以通过在VM中创建一个公共(public)属性,然后将CB中的值“注入(inject)”到VM中的方式来解决此错误。我知道这是可行的,但这是获得想要的行为的一种round回方式,这一点也不简单,而且我确信这是错误的处理方式。

我四处搜寻,并尝试了以下操作:

    FontSize="{Binding RelativeSource={RelativeSource Self},Path="MyFontSize"

(其中“MyFontSize”是一个公共(public)int属性)和我发现的各种其他示例,但没有一个起作用。

因此,具体来说,如果我的CodeBehind类称为NameChangeSetupMainWindow,并且该属性存在于“MyFontSize”属性中,
public partial class NameChangeSetupMainWindow : Window
{
    private int m_fontSize = 14;
    public int MyFontSize
    {
        get { return m_fontSize; }
        set
        {
            if (m_fontSize != value))
            {
                m_fontSize = (value > 0) ? value : 10;
            }
        }
    }
    ...
    ... rest of the class...
    ...
}

VM被称为NameChangeSetupViewModel,这就是“真实”数据所在的位置,并且DataContext指向ala:
<Window.DataContext>
    <local:NameChangeSetupViewModel/>
</Window.DataContext>

XAML中仅将那些UI项(与UI相关的工具提示,字体大小等)绑定(bind)到CodeBehind中的变量而不是将其容纳在VM中的语法是什么?

在此先感谢您提供的任何指导。

最佳答案

您可以使用 RelativeSource AncestorType 绑定(bind)到 View 本身的属性:

<TextBlock FontSize="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=MyFontSize}" />

使用ElementName应该也可以工作:
<Window x:Name="window">

    <TextBlock FontSize="{Binding ElementName=window,Path=MyFontSize}" />
</Window>

编辑

这是我已经确认可以正常工作的示例:

XAML
<Window x:Class="WpfAbc.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    ToolTip="{Binding RelativeSource={RelativeSource Self},Path=MyToolTip}"
    >
    <Grid>
        <TextBlock Text="hello world" FontSize="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=MyFontSize}" />
    </Grid>
</Window>

后面的代码
public partial class MainWindow : Window
{
    private int m_fontSize = 20;
    public int MyFontSize
    {
        get { return m_fontSize; }
        set
        {
            if (m_fontSize != value)
            {
                m_fontSize = (value > 0) ? value : 10;
            }
        }
    }

    public string MyToolTip
    {
        get { return "hello world"; }
    }

    public MainWindow()
    {
        InitializeComponent();
    }
}

关于此主题的文章:
  • The RelativeSource markup extension
  • XAML binding declarations

  • 相关背景:
  • "Namescopes" in XAML(当使用“ElementName”绑定(bind)到源时,源元素必须在同一名称范围内)
  • Visual tree vs logical tree in XAML(不在可视树中的元素(如Popup和ContextMenu,不继承DataContext。从这些元素进行绑定(bind)需要像"data context spy"技术一样的变通方法。)
  • 关于c# - 绑定(bind)到ViewModel和CodeBehind中的属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20155696/

    10-13 04:39
    查看更多