绑定到ViewModel和CodeBehind中的属性 [英] Binding to properties in both the ViewModel and CodeBehind

查看:42
本文介绍了绑定到ViewModel和CodeBehind中的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have what I'm sure is a ridiculously ignorant question, but I'm asking it anyways because I've searched and searched and either don't understand the solutions I'm seeing or not finding exactly the answer I seek.

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

I have an MVVM application. My XAML is setup with the DataContext set to the VM where the data items on the screen are populated from the VM's properties. My CodeBehind doesn't fiddle with the data, only things relating to the screen.

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

What I want to do now is bind certain UI elements to properties in the foo.xaml.cs (CodeBehind) file. For example, I want to specify FontSize's bound to properties in the CB so that in the WindowInitialized handler in the CB, it can detect screen sizes and change one variable to which all the screen items' FontSize= are bound.

我可以通过在我的VM中创建一个公共属性,然后将CB中的值注入"到VM中来解决这种错误的方法.我知道这是可行的,但这是获得所需行为的一种round回方式,这一点也不简单,而且我确信这是错误的处理方式.

I can solve this the wrong way by creating a public property in my VM and then "inject" the value from the CB into the VM. I know that will work, but it's a roundabout way to get the behavior I want, it's not at all straightforward, and I feel confident it's the wrong way to proceed.

我到处搜寻,并尝试过类似的事情:

I searched around and have tried things like:

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

(其中"MyFontSize"是一个公共int属性)和我发现的许多其他示例,但没有一个起作用.

(where "MyFontSize" is a public int property) and a variety of other examples I found, but none have worked.

特别是,如果我的CodeBehind类名为 NameChangeSetupMainWindow ,而这就是"MyFontSize"属性所在的位置,则

So specifically, if my CodeBehind class is called NameChangeSetupMainWindow and that's where the "MyFontSize" property lives,

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...
    ...
}

,虚拟机称为 NameChangeSetupViewModel ,这是真实"数据所在的位置,DataContext指向ala:

and the VM is called NameChangeSetupViewModel and that's where the "real" data lives and the DataContext points ala:

<Window.DataContext>
    <local:NameChangeSetupViewModel/>
</Window.DataContext>

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

what is the syntax in XAML to bind just those UI items (tooltips related to the UI, font sizes, etc) to variables in the CodeBehind instead of housing them in the VM?

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

Thanks in advance for any guidance you can supply.

推荐答案

您可以使用

You can use RelativeSource AncestorType to bind to properties of the view itself:

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

使用 ElementName 应该也可以正常工作:

Using ElementName should work as well:

<Window x:Name="window">

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


修改

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

Here is an example that I've confirmed working:

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();
    }
}

有关此主题的文章:

相关背景:

  • "Namescopes" in XAML (when binding to a source using "ElementName", the source element must be in the same namescope)
  • Visual tree vs logical tree in XAML (elements not in the visual tree, like Popup and ContextMenu, do not inherit DataContext. Binding from these elements requires a workaround like the "data context spy" technique.)

这篇关于绑定到ViewModel和CodeBehind中的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆