Связывание данных Windows Phone: кросс-нить - PullRequest
1 голос
/ 30 ноября 2011

у нас проблема с привязкой данных на Windows Phone (с использованием xaml). Я создал простой пример, который должен позволить воспроизвести проблему. Вот наша модель-класс:

public class Data : INotifyPropertyChanged
{
    private int value = 0;
    public int Value
    {
        get
        {
            return value;
        }
        set
        {
            this.value = value;

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

    public event PropertyChangedEventHandler PropertyChanged;

    public Data()
    {
        var t = new Thread(new ThreadStart(() =>
        {
            while (true)
            {
                Thread.Sleep(2000);
                Value += 1;
            }
        }));
        t.IsBackground = true;
        t.Start();
    }
}

, который использует поток для обновления значения-свойства и запуска события PropertyChanged.

Теперь я хочу связать это значение-свойство с графическим элементом управления:

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <TextBlock Text="{Binding Path=Value}" />
    </Grid>

    public MainPage()
    {
        InitializeComponent();

        DataContext = new Data();
    }

когда значение изменяется впервые (и событие PropertyChanged запускается), система привязки данных пытается скопировать значение Data.Value в TextBlock.Text, что приводит к недопустимому исключению между потоками, так как это событие не выстрелил в потоке пользовательского интерфейса.

мой вопрос: разве инфраструктура привязки данных .NET не может распознать, что я привязан к элементу управления пользовательского интерфейса, и выполнить переключение потоков самостоятельно? я знаю, что могу просто использовать диспетчер для запуска события PropertyChanged в главном потоке, но я бы хотел, чтобы мой класс модели был более отделен от компонента графического интерфейса. Есть ли лучшее решение этой проблемы? я не могу использовать подход DependencyObject, потому что наш основной проект (который содержит класс модели) должен работать на Windows Phone и Android, а Android не поддерживает пространство имен System.Windows.

Ответы [ 2 ]

0 голосов
/ 26 ноября 2012

Мне так нравится:

public event PropertyChangedEventHandler PropertyChanged;
    private void PropertyEventChanged(string propertyName)
    {
        if (PropertyChanged == null) return;

        if (Application.OpenForms.Count > 0 && Application.OpenForms[0].InvokeRequired)
            Application.OpenForms[0].Invoke(new MethodInvoker(() => PropertyChanged(this, new PropertyChangedEventArgs(propertyName))));
        else
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
0 голосов
/ 30 ноября 2011

Один из способов решить эту проблему - сохранить ссылку на диспетчер в вашей модели представления и использовать ее только для выполнения события измененного свойства, если оно не равно нулю.Затем вы можете установить свойство диспетчера в конструкторе вашей виртуальной машины.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...