jbe2277 / waf

Win Application Framework (WAF) is a lightweight Framework that helps you to create well structured XAML Applications.
MIT License
708 stars 128 forks source link

x:Bind doesn't work, but Binding does #8

Closed handflucht closed 6 years ago

handflucht commented 6 years ago

Hi,

first at all, thanks for this project. I used it in several projects and it works very well. Currently I am developing my first UWP-app and I have some troubles with binding. In the following example, the Binding-cmd works, but the x:bind doesn't:

IMainView

  public interface IMainView : IView
    {
        void Show();
    }

MainViewModel

[Export, Shared]
    public class MainViewModel : ViewModelCore<IMainView>

    {
        private string _someStringProperty;

        [ImportingConstructor]
        public MainViewModel(IMainView view) : base(view)
        {
        }

        public String SomeStringProperty
        {
            get => "this is some test";
            set => SetProperty(ref _someStringProperty, value);
        }

        public ICommand SuperCommand { get; set; }

        public void Show()
        {
            ViewCore.Show();
        }
    }

MainPage.xaml

<Page
    x:Class="A.Presentation.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <StackPanel>
        <TextBox Text="{x:Bind ViewModel.SomeStringProperty}"  Background="Aqua" />
        <TextBox Text="{Binding SomeStringProperty}"  Background="Aqua"/>

        <Button Content="Press me" Command="{x:Bind ViewModel.SuperCommand}"/>
    </StackPanel>
</Page>

MainPage.xaml.cs

using System.Composition;
using Windows.UI.Xaml;
using AuditExpert.Application.ViewModels;
using AuditExpert.Application.Views;

namespace A.Presentation
{
    [Export(typeof(IMainView)), Shared]
    public sealed partial class MainPage : IMainView
    {
        public MainPage()
        {
            InitializeComponent();

            ViewModel = (MainViewModel)DataContext;
        }

        public MainViewModel ViewModel { get; }

        public void Show()
        {
            Window.Current.Content = this;
            Window.Current.Activate();
        }
    }
}

As you can see I am binding the value from SomeStringProperty to a textbox. First with x:Bind, the second time with Binding. The textbox which makes usage of binding works fine, the one with x:bind doesn't show a value at all. If I put a breakpoint on the the getter of the SomeStringProperty it is only accessed once.

Am I missing something?

jbe2277 commented 6 years ago

Thanks for the feedback. Please note that your issue has nothing to do with the Win Application Framework (WAF).

I have seen two possible issues in your code sample:

  1. The DataContext is not yet set within the constructor. The ViewModel property will be initialized with null. That's the reason why the NewsReader sample application uses Lazy to initialize the ViewModel property.
    public MainPage()
    {
    InitializeComponent();
    ViewModel = (MainViewModel)DataContext;   // == null
    }
  2. x:Bind uses by default Mode=OneTime. In your sample add Mode=TwoWay to x:Bind.
handflucht commented 6 years ago

Thank you very much for answering my questions, even if it's not a bug of the framework.

Could you explain shortly, how to modify the code, that it would work without an LazyModel? we already do so in the WPF-area.

Thanks in advance!