WPF C # Databinding - MessageBox.Show - PullRequest
0 голосов
/ 21 мая 2018

Позвольте мне начать с того, что я прочитал так много тем, что у меня болит голова, я пробовал большинство из них и до сих пор не добился успеха.

Мои проблемы довольно просты.У меня есть статус, с которым я хочу обновить элемент управления, у меня есть TextBox, связанный с классом объекта.

Когда я выполняю код, textbox.Text обновляется, а не отображается.То, что я заметил, было, если я использую другие ориентированные на Windows вещи, с которыми я знаком из форм, таких как MessageBox.Show ();внутри моего цикла он прерывает MainWindow, и текстовое поле обновляется ..!

Что именно находится в MessageBox.Show (), который позволяет / заставляет / заставляет рендеринг произойти, и я могу не просто вызвать это напрямую?То, как я это сделал, кажется самой простой версией, когда вам понадобится привязка данных, чтобы просто работать из коробки без какой-либо громоздкой работы ... надеюсь, я упускаю простую кнопку ...

Любойпомощь будет иметь большое значение.Заранее спасибо за ваше время.

public partial class MainWindow : Window{

private ExampleDataClass objClass = null;

public MainWindow()
{
    InitializeComponent();
    objClass = new ExampleDataClass();
    this.DataContext = objClass;
}

public int j = 0;

private string _someLocalString = "";

public string SomeLocalString
{
    get { return _someLocalString; }
    set { _someLocalString = value; }
}

public string strstr = ""; 


private void textBox_TextChanged(object sender, TextChangedEventArgs e)
{
    //MessageBox.Show(""); // this will make it work.. 
}

private void button_Click(object sender, RoutedEventArgs e)
{

    SomeLongRunningCode(out strstr);
}

public void SomeLongRunningCode(out string SomeProperty)
{
    for (int i = 1; i <= 600; i++)
    {
        SomeLocalString = i.ToString();
        objClass.X = _someLocalString;

        //   BindingOperations.GetBindingExpressionBase(textBox, TextBox.TextProperty).UpdateTarget();
        //    textBox.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,
        //       new Action(delegate() { textBox.Text = i.ToString();}));
    }



    SomeProperty = "Exited SomeLongRunningCode";
}}}

<Window x:Class="DataBinding.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:DataBinding"
    mc:Ignorable="d"
    Title="MainWindow" Height="109.157" Width="176.303">
<Grid x:Name="myGrid">
    <TextBox x:Name="textBox" Text="{Binding X,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Focusable = "true" HorizontalAlignment="Left" Height="23" Margin="22,14,0,0" TextWrapping="Wrap"  VerticalAlignment="Top" Width="120" TextChanged="textBox_TextChanged" />
    <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="24,46,0,0" VerticalAlignment="Top" Width="75" Click="button_Click"/>

</Grid>

public class ExampleDataClass : INotifyPropertyChanged
{

    private string _x = "";
    public string X
    {
        get { return _x;}
        set
        {
            if (_x != null)
            {
                _x = value;
                OnPropertyChanged("X");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string info)
    {
        var handler = this.PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(info));
        }
    }

}}

1 Ответ

0 голосов
/ 21 мая 2018

textBox не обновляется, потому что поток блокируется во время цикла for.

Если вы выполните SomeLongRunningCode асинхронно, вы увидите, что ваш код работает как задумано.

private void button_Click(object sender, RoutedEventArgs e)
{

    Task.Run(() => SomeLongRunningCode(out strstr));
}

public void SomeLongRunningCode(out string SomeProperty)
{
    for (int i = 1; i <= 600; i++)
    {
        SomeLocalString = i.ToString();
        objClass.X = _someLocalString;
        Thread.Sleep(100);   // Slowing down so we can see the text change
    }



        SomeProperty = "Exited SomeLongRunningCode";
}
...