|
How does that get the UI to refresh? The event is raised, but so what? I need the bound value in the UI to update
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Read the link:
The data binding engine recognizes when the property's value changes if a static event is raised.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
You know, I read that and my mind glossed right over it.
So I now have:
<TextBlock Text="{Binding Source={x:Static local:AppCore.CurrentUser}, Path=FullName, Mode=TwoWay}"/>
and in AppCore:
public static class AppCore
{
public static event EventHandler CurrentUserChanged;
public static UserEntity CurrentUser { get; private set; }
public static bool Login(CredentialEntity credentials)
{
var loggedIn = false;
LoginResponse response = _appSecurity.Login(credentials);
if (response.Result == Result.Success)
{
CurrentUser = response.User;
CurrentUserChanged?.Invoke(null, EventArgs.Empty);
loggedIn = true;
}
return loggedIn;
}
}
when I log in, the Full name doesn't appear in the UI. Output Windows doesn't reveal anything.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
It's probably the x:Static markup extension. Try changing the binding to:
<TextBlock Text="{Binding Path=(local:AppCore.CurrentUser.FullName), Mode=TwoWay}"/>
WPF 4.5: Binding and change notification for static properties - Pete Brown's 10rem.net[^]
EDIT: This blog seems to confirm it:
It does not work with the x:Static extension
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
ya I tried that already. I get "Nested types are not supported: AppCore.Currentuser"
I read a blog post about WPF getting confused with all the '.'s.. something about confusion between the nesting and property attributes.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Did you try surrounding the path with brackets?
Path=(local:AppCore.CurrentUser.FullName)
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Yes
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
OK. How about binding the DataContext to the user, and then binding the Text to the name?
<TextBlock DataContext="{Binding Path=(local:AppCore.CurrentUser)}" Text="{Binding Path=FullName, Mode=TwoWay}"/>
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
SUCCESS!
I followed the Second Approach on that blog you posted and it worked!
public static class AppCore
{
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;
public static UserEntity CurrentUser { get; private set; }
private static string _FullName;
public static string FullName
{
get { return _FullName; }
set
{
if (_FullName != value)
{
_FullName = value;
NotifyStaticPropertyChanged("FullName");
}
}
}
private static void NotifyStaticPropertyChanged(string propertyName)
{
if (StaticPropertyChanged != null)
StaticPropertyChanged(null, new PropertyChangedEventArgs(propertyName));
}
public static bool Login(CredentialEntity credentials)
{
var loggedIn = false;
LoginResponse response = _appSecurity.Login(credentials);
if (response.Result == Result.Success)
{
CurrentUser = response.User;
FullName = response.User.FullName;
loggedIn = true;
}
return loggedIn;
}
}
Thanks for your help & patience!!
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
What's the best way to make a Chess board using WPF and MVVM?
On startup I want to create an 8x8 grid of Squares.
Right now I added all 64 Sqaures to a <grid> in the XAML. But to make this work with MVVM I'll need some form of binding.
Not sure of how to architect this.
Anyone?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Kevin Marois wrote: What's the best way to make a Chess board using WPF and MVVM? I asked myself the same question before working on StockChess[^] and I'm guessing you've figured out by now that the approach you've mentioned will not get you the result you want. If you want it to be MVVM friendly you will just have to create an items control that uses a Grid for its ItemsPanelTemplate . If you use an items control that enables you to select an item then even better, like a ListBox .
"As beings of finite lifespan, our contributions to the sum of human knowledge is one of the greatest endeavors we can undertake and one of the defining characteristics of humanity itself"
|
|
|
|
|
I have a MetroTabControl that I want to use to display several RDP connections using the TabItems, the problem that I`m having is, after I establish the first RDP connection, If I switch tabItem, the view goes out of scope and I loose the connection in that TabItem (so each time I switch tabitem the view goes out of scope). I wanted to maintain the connection alive in each TabItem and control the close of the view with the CloseTabCommand using the tabitem CloseButton.
In this sample the RemoteClients is an Observable collection of an objectClass that each TabItem will bind to
e.g. ObservableCollection<RdpClient>RemoteClients{get; set;}
The SelectedRemoteClient represents the current selected object (RdpClient).
RemoteDesktopBaseControlView is the view that each TabItem will have and has all the bindings for the RdpClient object
<Grid>
<controls:MetroTabControl VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding RemoteClients, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedRemoteClient, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
CloseTabCommand="{Binding CloseTabCommand}" >
<controls:MetroTabControl.Resources>
<DataTemplate x:Key="contentTemplate" x:Shared="False">
<local:RemoteDesktopBaseControlView />
</DataTemplate>
</controls:MetroTabControl.Resources>
<controls:MetroTabControl.ItemContainerStyle>
<Style TargetType="{x:Type controls:MetroTabItem}">
<Setter Property="Header" Value="{Binding ViewTitle, UpdateSourceTrigger=PropertyChanged}" />
<Setter Property="controls:MetroTabItem.ContentTemplate" Value="{StaticResource contentTemplate}"/>
<Setter Property="controls:MetroTabItem.CloseButtonEnabled" Value="True"/>
<Setter Property="controls:MetroTabItem.CloseTabCommandParameter" Value="{Binding}" />
<Setter Property="controls:ControlsHelper.HeaderFontSize" Value="16" />
<Setter Property="controls:ControlsHelper.HeaderMargin" Value="4" />
</Style>
</controls:MetroTabControl.ItemContainerStyle>
</controls:MetroTabControl>
</Grid>
Any Ideas how to fix this?
|
|
|
|
|
I have no idea what MetroTabControl is (other than a TabControl), but it sounds like it inherits the problem from the standard TabControl whereby switching tabs closes the view and creates a new one. If this is the case, you'll need to put in a version of the fix described here[^].
This space for rent
|
|
|
|
|
Hi, you`re right the controls:MetroTabControl is just a stylized version of the TabControl, removing the "controls:Metro" and leaving the <tabcontrol the="" behavior="" is="" same.="" i="" try="" extension="" but="" not="" working="" still="" same="" and="" it="" leaks="" memory.="" created="" tabcontrolex.cs="" add="" <style="" targettype="{x:Type local:TabControlEx}"> in the <usercontrol.resources> for the view but no change... do I need to do something else?
Thank you
|
|
|
|
|
|
I'm creating a chess game.
The board is made up of a grid of user controls called BoardSqaure:
<UserControl x:Class="Chess.UI.WPF.Controls.BoardSquare"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Chess.UI.WPF.Controls"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300">
<ContentPresenter Content="{Binding Piece}"/>
</UserControl>
and
namespace Chess.UI.WPF.Controls
{
public partial class BoardSquare : UserControl
{
public BoardSquare()
{
InitializeComponent();
}
public static readonly DependencyProperty PieceProperty =
DependencyProperty.Register("Piece",
typeof(PieceBase),
typeof(BoardSquare),
new PropertyMetadata(null));
public PieceBase Piece
{
get { return (PieceBase)GetValue(PieceProperty); }
set { SetValue(PieceProperty, value); }
}
}
}
The DP Piece will hold an instance of PieceBase, which can be King, Queen, Rook.. etc.
To load the board in the code behind I'm trying to do
private void SetupBoard()
{
BoardSquare square = board.Children.Cast<BoardSquare>().First(e => Grid.GetRow(e) == 0 && Grid.GetColumn(e) == 0);
square.Piece = new RookBlack();
square = board.Children.Cast<BoardSquare>().First(e => Grid.GetRow(e) == 0 && Grid.GetColumn(e) == 1);
square.Piece = new BishopBlack();
.
.
.
}
However the pieces never shows up.
What am I doing wrong here?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 5-Dec-16 17:08pm.
|
|
|
|
|
Kevin Marois wrote: BoardSquare square = board.Children.Cast<BoardSquare>().First(e => Grid.GetRow(e) == 0 && Grid.GetColumn(e) == 0);
square.Piece = new RookBlack();
square = board.Children.Cast<BoardSquare>().First(e => Grid.GetRow(e) == 0 && Grid.GetColumn(e) == 1);
square.Piece = new BishopBlack();
Well first off the bishop doesn't go next to the rook In all seriousness though, I see nothing wrong with the code you've posted. Could you edit with all relevant Queen code? I'm assuming the other pieces are displaying properly?
|
|
|
|
|
No piece that I assign to the Piece property shows up
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
There's really no way to tell from the code posted what's going on. ContentPresenter is generally used in a ControlTemplate . Using it raw like this means there are SOO many variables that could affect what's going on. Is there a DataTemplate associated with the type? What type of element is PieceBase ? Does it have any templates associated with it?
ContentPresenter is a very dynamic class. You can see just how many different things it checks and may or may not apply in the remarks section of its MSDN page[^].
|
|
|
|
|
OK, so what would be the right architecture here for a chess board? Keep in mind that the user will drag/drop pieces around, and pieces will also need to be programmatically added & removed.
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
You can programmatically remove anything. For drag and drop, the MSDN article Walkthrough: Enabling Drag and Drop on a User Control[^] has everything you need. As far as architecture, that's entirely a personal choice.
You can derive your UserControl from ContentControl and use a ContentPresenter . You could use Image controls[^] inside each Grid square. I mean WPF is a huge and flexible architecture.
EDIT: I forgot to mention, you can use the ContentPresenter like that - nothing inherently wrong with it. There's just not enough information for me to say why it might not be working without all the code that could affect it.
|
|
|
|
|
There's too many things that you may have accounted for that we can't see:
Width
Height
Visibility
Transparency
Z-Order
Background color
Foreground color
Top
Left
Rendering
...
|
|
|
|
|
In a chess app I wrote some time back: WPF: P2P Chess[^], I took an approach similar to what you're doing. I had a bunch of user controls to represent the pieces. Over time I grew uncomfortable with this and decided to take an MVVM friendly approach for an app I'm currently developing, where the user plays against Stockfish. The chess board in my current app is a ListBox whose ItemsPanel is a Grid with eight row and eight columns. The ItemsSource property of the ListBox is bound to a collection of objects that implement the same interface. The collection, in the View Model, is made up of BoardSquare s and ChessPiece s. The DataTemplate of the ListBox is an Image that uses MultiDataTrigger s to determine the appropriate image to display depending on the type of object. I'll be posting an article soon, maybe tommorrow, where you can dig deeper into the code.
"As beings of finite lifespan, our contributions to the sum of human knowledge is one of the greatest endeavors we can undertake and one of the defining characteristics of humanity itself"
|
|
|
|
|
I look forward to seeing it.
One question... When setting up the board, the board is layout grid with 8 rows & 8 columns, and the pieces are added to the grid during setup.
How do you reverse the board for the other player?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Kevin Marois wrote: How do you reverse the board for the other player? By reverse I guess you mean flip. I rotate the ListBox and switch its DataTemplate . One DataTemplate has the Image control rotated at an angle of 0 while the other has the Image control rotated at an angle of 180 degrees.
"As beings of finite lifespan, our contributions to the sum of human knowledge is one of the greatest endeavors we can undertake and one of the defining characteristics of humanity itself"
|
|
|
|