简体   繁体   中英

TextBlock is not updating using ViewModel's property

I am working on a small wpf application, i am showing status using a textblock and for achieving this i have bind a property from a view model. I have mapped everything despite this UI is not showing any value. I am pasting code as below.

App.xaml.cs

public LogViewModel LogTextVm { get; set; }

ViewModelLocator.cs

App thisApp = (App)Application.Current;
public ViewModelLocator()
{
    thisApp.LogTextVm = new LogViewModel();
}

LogViewModel.cs

public class LogViewModel : INotifyPropertyChanged
{
    private string _logText { get; set; }
    public string LogText
    {
        get => _logText;
        set
        {
            if(_logText!=value)
            {
                _logText = value;
                OnPropertyChnaged("LogText");
            }
        }
    }
    private void OnPropertyChnaged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

MainWindow.xaml

xmlns:vm="clr-namespace:MyApplication.ViewModels"
<Window.Resources>
    <vm:ViewModelLocator x:Key="Locator"/>
</Window.Resources>

<TextBlock Grid.Column="0" Text="{Binding LogText, Mode=TwoWay}" DataContext="{Binding LogViewModel, Source={StaticResource Locator}}"
                       FontFamily="segoe UI" FontWeight="SemiBold" FontStyle="Italic" Foreground="White" />

MainWindow.xaml.cs

private App thisApp = (App)Application.Current;
public MainWindow()
{
     InitializeComponent();
}
private async void CallGraphButton_Click(object sender, RoutedEventArgs e)
{
     thisApp.LogTextVm.LogText = "Status : Loading data ...";
}

Can anyone help me, where i am doing mistake?

You have to assign MainWindow.DataContext with the same LogViewModel instance that is created by ViewModelLocator

DataContext="{Binding LogViewModel, Source={StaticResource Locator}}" can it create a new instance of the ViewModelLocator (and therefore thus new LogViewModel ) ?

Please put the breakpoint at the thisApp.LogTextVm = new LogViewModel(); line and check is it executed twice?

UPD VS output shows binding error for your code

System.Windows.Data Error: 40 : BindingExpression path error: 'LogViewModel' property not found on 'object' ''ViewModelLocator' (HashCode=37320431)'. BindingExpression:Path=LogViewModel; DataItem='ViewModelLocator' (HashCode=37320431); target element is 'StackPanel' (Name=''); target property is 'DataContext' (type 'Object')

You are binding to the wrong names unfortunately. To fix the binding I had to change the code as below:

ViewModelLocator

public class ViewModelLocator
{
    public ViewModelLocator()
    {
        App thisApp = (App)Application.Current;
        LogTextVm = new LogViewModel();
        thisApp.LogTextVm = LogTextVm;
    }

    public LogViewModel LogTextVm { get; set; }

}

MainWindow.xaml

<Grid>
    <StackPanel  DataContext="{Binding LogTextVm, Source={StaticResource Locator}}">
        <TextBlock  Text="label:" />
        <TextBlock  Text="{Binding LogText, Mode=TwoWay}" />
        <Button Content="click" Click="Button_Click" />
    </StackPanel>
</Grid>

DataContext="{Binding LogTextVm, Source={StaticResource Locator}}"> creates ViewModelLocator instance and binds StackPanel.DataContext to the ViewModelLocator.LogTextVm property.

The <TextBlock Text="{Binding LogText, Mode=TwoWay}" /> binds to the LogText for the current DataContext (which is LogTextVm property value)

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