如何将文本框绑定到类Property

时间:2013-12-11 04:30:56

标签: c# wpf binding

我想将类中的属性单向绑定到文本框。但有麻烦,scenerio在我的代码下面,获取test_string的字符串值到我的视图。这段代码我试过但似乎没有用。我需要做什么?

具有属性的类:

namespace config
{
    class tester : INotifyPropertyChanged
    {
        public tester()
        {
        }

        private string test_string;

        public string Test{
            get { return test_string; }
            private set
            {
                test_string = value;
                RaisePropertyChanged("Test");
            }
        }

        public void dotest(){
            ... do some testing
            Test = "Past point one"
            ... do some more testing
            Test += "Past point two"
            ... do some more testing
            Test += "Finished testing"
        }
    }
}

视图模型

using config
namespace notif
{
    class t_viewmodel
    {
        public t_viewmodel()
        {
        }

        Tester tester = new Tester();

        public string TestLink
        {
            get { return tester.Test; }
        }

        public void run_test()
        {
            tester.dotest();
        }
    }
}

查看

<Window x:Class="notif.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="263" Width="539"
        xmlns:viewmodel="clr-namespace:notif" >

    <Window.DataContext>
        <viewmodel:t_viewmodel/>
    </Window.DataContext>

    <Grid>
        <TextBox Name="txtTestMessage" Text="{Binding TestLink}" />
        <Button Content="Do Test" Name="button1" />
        <!--Pretending the button it goes to viewmodels run_test()-->
    </Grid>
</Window> 


[EDIT1] 由于进程正在通过dotest运行,所以直到它完成文本框的填充后,每次设置Test属性时我能做些什么才能进行此更新?


[EDIT2] 已更改

public void SQLDBAccessTest(string db)
{
    if (test_debug)
        ConnectionTest = "Test started. " + DateTime.Now;

    string conn_string = "";

    try
    {
        conn_string = createConnectionString(db);
        if (test_debug)
            ConnectionTest += "\nConnection string = '" + conn_string + "'";
    }
    catch (Exception ex)
    {
        throw ex;
    }

    try
    {
        if (test_debug)
            ConnectionTest += "\nCreating connection to database...";

        cnn = new SqlConnection(conn_string);

        if (test_debug)
            ConnectionTest += "\nConnection created.";

        if (test_debug)
            ConnectionTest += "\nEstablishing open connection to database...";

        cnn.Open();

        if (test_debug)
            ConnectionTest += "\nEstablished connection to database.";
        if (test_debug)
            ConnectionTest += "\nClosing connection to database...";

        cnn.Close();

        if (test_debug)
            ConnectionTest += "\nConnection closed.";
    }
    catch (Exception ex)
    {
        if (test_debug)
            ConnectionTest += "\nAn error has occured whilst connecting to the database.\n\t - " + ex.Message;

        throw ex;
    }

    if (test_debug)
        ConnectionTest += "\nTest complete. " + DateTime.Now;
}

private string createConnectionString(string db)
{
    string tempConString = ConStr;

    try
    {
        TestConnSettingsFile();
        setDBDataSourceAndSecurity();

        if (test_debug)
            ConnectionTest += "\nCreating connection string...";

        tempConString = tempConString.Replace("<SERVER>", db_datasource);
        tempConString = tempConString.Replace("<DB>", db);
        tempConString = tempConString.Replace("<SECURITY>", db_security);

        if (test_debug)
            ConnectionTest += "\nCreated connection string.";
    }
    catch (Exception ex)
    {
        throw ex;
    }
    return tempConString;
}

private bool TestConnSettingsFile()
{
    bool settingsFileExist = false;
    string filePath = "";

    if (test_debug)
        ConnectionTest += "\nTesting for encrypted connection file...";

    try
    {
        string directory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
        filePath = System.IO.Path.Combine(directory, "afx.settings");

        if (System.IO.File.Exists(filePath))
        {
            settingsFileExist = true;
            xmlSettingsFilePath = filePath;

            if (test_debug)
                ConnectionTest += "\nThe encrypted connection file has been found at: " + filePath;
        }
        else
        {
            if (test_debug)
                ConnectionTest += "\nThe encrypted connection file could not be found at: " + filePath;
            throw new Exception("The encrypted connection file could not be found at: " + filePath);
        }
    }
    catch (Exception ex)
    {
        if (test_debug)
            ConnectionTest += "\nError occured while testing if encrypted file exists:\n\t - " + ex.Message;
        throw ex;
    }

    return settingsFileExist;
}

private bool setDBDataSourceAndSecurity()
{
    bool result = false;

    if (test_debug)
        ConnectionTest += "\nRetrieving encrypted connection...";

    try
    {
        if (System.IO.File.Exists(xmlSettingsFilePath))
        {
            XmlTextReader reader = null;

            if (test_debug)
                ConnectionTest += "\nReading connection xml file...";

            // Load the file with an XmlTextReader
            reader = new XmlTextReader(xmlSettingsFilePath);
            // Read the File
            while (reader.Read())
            {
                //checking where read text is element and and name is “DataSource”
                if (reader.NodeType == XmlNodeType.Element && reader.Name == "DataSource")
                {
                    if (test_debug)
                        ConnectionTest += "\nReading data source...";

                    //assigning ReadElementstring to strCmb1.
                    string datasource = reader.ReadElementString();

                    if (test_debug)
                        ConnectionTest += "\nData source = " + db_datasource;
                }
                if (reader.NodeType == XmlNodeType.Element && reader.Name == "Security")
                {
                    if (test_debug)
                        ConnectionTest += "\nReading security...";

                    string security = reader.ReadElementString();

                    if (test_debug)
                        ConnectionTest += "\nSecurity = " + db_security;
                }
            }
            if (test_debug)
                ConnectionTest += "\nClosing connection xml file...";

            reader.Close();
            reader = null;

            if (test_debug)
                ConnectionTest += "\nSuccess retrieving encrypted connection...";

            result = true;
        }
        else
        {
            if (test_debug)
                ConnectionTest += "\nLost connection xml file, could not be found at: " + xmlSettingsFilePath;
            throw new Exception("The configuration file, setup for database connectivity could not be found.");
        }
    }
    catch (Exception ex)
    {
        if (test_debug)
            ConnectionTest += "\nError occured while setting data source and security:\n\t - " + ex.Message;
        throw ex;
    }
    return result;
}

2 个答案:

答案 0 :(得分:1)

您绑定的属性为TestLink,但未通知其更改。相反,您可以公开Tester实例本身:

public string Tester
{
    get { return tester; }
}

现在您只需绑定到Tester.Test即可获得更改通知:

<TextBox Name="txtTestMessage" Text="{Binding Tester.Test}" />

修改

要使用长时间运行的任务连续更新UI,您需要使用后台线程。需要将UI更新(即,设置“测试”)分派回UI线程。这是一个例子:

public void dotest(){
    var dummyAction = new Action( () => Thread.Sleep(1000) );
    var first = new Task(dummyAction);
    var second = new Task(dummyAction);
    var third = new Task(dummyAction);

    first.ContinueWith(task =>
    {
        Application.Current.Dispatcher.BeginInvoke(new Action(() =>
        {
            Test = Environment.NewLine + "past point one";
        }));
        second.Start();
    });
    second.ContinueWith(task =>
    {
        Application.Current.Dispatcher.BeginInvoke(new Action(() =>
        {
            Test += Environment.NewLine + "past point two";
        }));
        third.Start();
    });
    third.ContinueWith(task => {
        Application.Current.Dispatcher.BeginInvoke(new Action(() =>
        {
            Test += Environment.NewLine + "Finished testing";
        }));
    });
    first.Start();
}

答案 1 :(得分:1)

在文本框中绑定TestLink属性,但不会通知属性更改。而不是你需要绑定Test的{​​{1}}属性。

Tester