ANSWER: Basically, I wasn't using Caliburn Micro properly. Using ContentControl was the proper way to bind my views and models. More here: Does Caliburn.Micro play nicely with user controls?
I'm using WPF with the Caliburn Micro framework. The program starts up with the GameViewModel.cs, which correctly syncs itself with the GameView.xaml.
From GameViewModel.cs I create four new PlayerViewModel()
, which sync correctly with PlayerView.xaml. In PlayerView.xaml I have a couple of bindings, everything all binds correctly, no problems, is updated just as expected and as I want..
But in the Output window, I'm getting all kinds of errors that the Bindings from PlayerView can't bind to GameViewModel.cs.
Now, great that the program works as expected, but all these errors made me worry enough to check what I'm doing wrong. Please help me out, what's going on here?
(My guess is that it's Caliburn related, and it tries to bind the x:Name
to something in GameViewModel because that's the startup project. If I -do- happen to be on the mark, how do I change it to bind properly?)
Error as follows:
System.Windows.Data Error: 40 : BindingExpression path error: 'TransformScaleX' property not found on 'object' ''GameViewModel' (HashCode=24649639)'. BindingExpression:Path=TransformScaleX; DataItem='GameViewModel' (HashCode=24649639); target element is 'TextBlock' (Name='ScaleX'); target property is 'Text' (type 'String')
System.Windows.Data Error: 40 : BindingExpression path error: 'TransformScaleY' property not found on 'object' ''GameViewModel' (HashCode=24649639)'. BindingExpression:Path=TransformScaleY; DataItem='GameViewModel' (HashCode=24649639); target element is 'TextBlock' (Name='ScaleY'); target property is 'Text' (type 'String')
List continues for a bit, same error for other properties too. Code as below, I trimmed out (seemingly?) irrelevant bits:
//This works fine
public class GameViewModel : PropertyChangedBase
{
private Game _model;
public GameViewModel() { _model = new Game(this); }
private PlayerViewModel _player1 = new PlayerViewModel("player1");
public PlayerViewModel Player1 { get { return _player1; } set { _player1 = value; NotifyOfPropertyChange("Player1"); } }
}
//This works fine too.
<UserControl>
<Grid Width="1280" Height="720" Background="Cyan">
<local:PlayerView cal:View.Model="{Binding Player1}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,220,0,0"/>
</Grid>
</UserControl>
//Works fine
public class PlayerViewModel : PropertyChangedBase
{
private Player _model;
public PlayerViewModel(string name)
{
Username = name;
_model = new Player(this);
}
//NotifyOfPropertyChange is handled properly elsewhere
public string TransformScaleX { get; set; }
public string TransformScaleY { get; set; }
}
//All binds with no issues.
<UserControl>
<Grid Width="288" Height="55">
<TextBlock x:Name="ScaleX" Visibility="Hidden" Text="{Binding TransformScaleX}"/>
<TextBlock x:Name="ScaleY" Visibility="Hidden" Text="{Binding TransformScaleY}"/>
</Grid>
</UserControl>