Binding to properties in both the ViewModel and CodeBehind

核能气质少年 提交于 2021-02-05 07:51:30

问题


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.

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.

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.

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"

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

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

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>

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.


回答1:


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

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

Using ElementName should work as well:

<Window x:Name="window">

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

Edit

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>

Code Behind

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

Articles on this topic:

  • The RelativeSource markup extension
  • XAML binding declarations

Related background:

  • "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.)


来源:https://stackoverflow.com/questions/20155696/binding-to-properties-in-both-the-viewmodel-and-codebehind

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!