質問

I am new to WPF, C# and xaml. I'd describe my knowledge as poor, but growing.

I have a very simple application. What I am trying to accomplish is the following:

I have a textbox, and I'm asking the user of the application to enter an email address. I'd like to store that variable somewhere, where I can write it to the screen later. So: 1. Get the email address (User hits a 'Next' button) 2. "Thanks an email will be set to " "when the utility is finished."

I'm using Blend with SketchFlow. I created a singleton class that allows me to store the variable.

namespace Mysillyapplication
{
public class ApplicationParameters
{
    private static ApplicationParameters _instance;
    private string _emailAddress;

    public static ApplicationParameters Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new ApplicationParameters();
            }
            return _instance;
        }

    }

    public string EmailAddress
    {
        get { return _emailAddress; }
        set
        {
            _emailAddress = value;
        }
    }
}

The code for the page that gets the email address:

namespace Mysillyapplication
{
/// <summary>
/// Interaction logic for BasicParameters.xaml
/// </summary>
public partial class BasicParameters : UserControl
{
    public BasicParameters()
    {
        this.InitializeComponent();
    }

    public string EmailAddress
    {
        get
        {
            return ApplicationParameters.Instance.EmailAddress;
        }
        set
        {
            ApplicationParameters.Instance.EmailAddress = value;
        }
 }
     }
   }

In my xaml I have the following lines:

<TextBox x:Name="email" HorizontalAlignment="Left" Height="23" Margin="32,65,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="291"/>

AND

<i:EventTrigger EventName="Click">
                <ei:ChangePropertyAction  TargetName="MySillyapplication_BasicParameters_Name" PropertyName="EmailAddress" Value="{Binding Text, ElementName=email}" />
                <pi:NavigateToScreenAction TargetScreen="DBSyncScreens.BeginSync"/>
            </i:EventTrigger>

AND Finally, I want to display it out on another page: In that page's CS I have the following lines:

public string EmailAddress
    {
        get
        {
            return ApplicationParameters.Instance.EmailAddress;
        }
        set
        {
            ApplicationParameters.Instance.EmailAddress = value;
        }
    }

And in the XAML:

<TextBlock HorizontalAlignment="Left" Height="25" Margin="10,35,0,0" Style="{DynamicResource BasicTextBlock-Sketch}" 
               VerticalAlignment="Top" Width="605" >
        <Run Text="A log of the sync will be sent to "/>
        <Run Text="{Binding EmailAddress, Mode=TwoWay}"/>
        <Run Text=". Click Next to begin the sync process."/>
    </TextBlock>

is wrong and doesn't work.

I could be doing this the wrong way. Anyone have any ideas on how to easily make that user variable email address easy to handle. I feel like what I'm trying to accomplish is very easy, yet I'm having so much difficulty with it.

get a variable, store it, access it on other pages.

役に立ちましたか?

解決

I wrote about this a bit in my blog post What is this "DataContext" you speak of?

To summarize, WPF applications have two layers: the UI layer and the data layer.

The data layer is the DataContext, and bindings are used in the UI layer to access data from the data later.

When you write <TextBox Text="{Binding EmailAddress}" />, you are telling WPF to look in the data layer (DataContext) behind the TextBox and bind to the EmailAddress property.

The DataContext is inherited down the visual tree, so typically you will only see the DataContext set once, such as

public SomeConstructor()
{
    this.InitializeComponent();
    this.DataContext = ApplicationParameters.Instance;
}

It should be noted that you can also specify other binding properties to access values from somewhere other than the current DataContext, such as ElementName or Source.

For example, since you are binding to a Singleton property, you could use the following syntax for your binding:

Text="{Binding Path=EmailAddress, 
               Source={x:Static my:ApplicationParameters.Instance}}"

This would set the source of your binding to your singleton object, so it would bind to ApplicationParameters.Instance.EmailAddress

For this to work, you'll also have to specify the "my" namespace, like this:

<Window ... xmlns:my="clr-namespace:MyNamespace" />

But to make a long story short, the reason why your binding won't work is because the DataContext behind your TextBlock is not ApplicationParameters.Instance, so it finds no EmailAddress property to bind to :)

他のヒント

It is because you haven't set your DataContext on your second page so it can't find EmailAddress.

In your page constructor try adding:

DataContext = this;

In the BasicParameters constructor, add the following code:

public BasicParameters()
{
    this.InitializeComponent();
    this.DataContext = ApplicationParameters.Instance;
}

HTH!

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top