简体   繁体   中英

Binding variables to XAML fields

I am Using C# & XAML with Visual Studio 2012

MS changed much of Visual Studio in 2012 that I have not been able to find working solutions on the web. I am new to C#/XAML so I am not familiar with Data Binding, if that is indeed the proper way to proceed.

I need to display variables from the App.xaml.cs file on the MainPage.xaml page. These variables change state every 100-300 msec., so requiring a refresh of the page each time the data changes is probably not a good idea.

Here are code snippets from my project:

App.xaml.cs defines the variables and modifies them in a dispatcherTimer:

namespace OpenGOTO
{
    public partial class App : Application
    {
        public static string DateStrZ = "";
        public static string FubarTest { get; set; }
    }
}

In MainPage.xaml (which is not always the current window) I have the TextBlock:

<TextBlock x:Name="UTC_Data" Text="2012-08-01 03:29:07Z" Padding="5" Style="{StaticResource TextBlockStyle1}" />

In MainPage.xaml.cs I have routines that are called by a dispatcherTimer that updates the fields:

public void SetFieldsTick()
{
    UTC_Data.Text = App.DateStrZ;
}

If I change this to

public static void SetFieldsTick() 

so that I can call it from the App.xaml.cs dispatcherTimer, I get the error message:

An object reference is required for the non-static field, method, or property 'OpenGOTO.MainPage.UTC_Data'

How do I either:

  1. Bind the data to the field (and will it automatically update without needing to refresh the whole window?)
  2. Create the correct references so that the dispatcherTimer in App.xaml.cs can call a routine in MainPage.xaml.cs that sets the fields in the XAML page.

To use a Binding that gets updates from the data you need a few things:

  • A property to bind to
  • Some implementation of change notification, usually using INotifyPropertyChanged or a DependencyProperty
  • An object instance on which the property is declared

You currently have none of these. Start by making an object that implements INotifyPropertyChanged with a property to store your data:

public class MyBindableObject : INotifyPropertyChanged
{
    private string _dateStr;
    public string DateStr
    {
        get { return _dateStr; }
        set
        {
            if (_dateStr == value)
                return;
            _dateStr = value;

            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("DateStr"));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

You can then expose a static instance of this from your App class and make updates to this instance whenever new data comes in:

    private static MyBindableObject _bindingContainer = new MyBindableObject();
    public static MyBindableObject BindingContainer
    {
        get { return _bindingContainer; }
    }

    public static void SetNewData()
    {
        // use this anywhere to update the value
        App.BindingContainer.DateStr = "<Your New Value>";
    }

Now you have everything you need for a Binding and you just need to expose it to your page. You can do this by setting the DataContext of your page, which is the default binding source:

    public MainPage()
    {
        this.InitializeComponent();
        DataContext = App.BindingContainer;
    }

Now you can bind your TextBlock :

    <TextBlock x:Name="UTC_Data"
            Text="{Binding Path=DateStr}"
            Padding="5" Style="{StaticResource TextBlockStyle1}"/>

Why can't you just call the UTC_Data from App.xaml.cs?

For example:

((MainPage) rootFrame.Content).UTC_Data.Text = DateStrZ;

Of course UTC_Data won't be accessible until you change it like this:

<TextBlock x:FieldModifier="public" x:Name="UTC_Data" Text="2012-08-01 03:29:07Z" Padding="5" Style="{StaticResource TextBlockStyle1}"/>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM