I'm developing a WPF App using MVVM architecture but I'm having an issue setting a current Model to a ViewModel.
Well, I'm currently trying to set a Model coming from a ViewModel (A:SectionCustomersViewModel) to another one (B:CustomerViewModel) but everytime the "currentModel" (CustomerViewModel's property) is setted it's just null and obviously the binded View to the CustomerViewModel shows nothing in controls.
I have already tried setting the model directly to the ViewModel but that didn't work, so I changed the strategic using a kind of publisher-subscriber pattern but it didn't work either.
It should be mentioned that i have done test with some data dummy to see if the user controls (textbox, combobox, etc.) are setted and effectively they are.
Time to see the code for more clearness (for a clearer and shorter code I just remove no-needed lines).
ViewModel A (SectionCustomersViewModel).
class SectionCustomersViewModel : ObservableObject, IPageViewModel
{
private event Action<CustomerModel> CustomerToCustomerViewModel;
public string Name => "Customers".ToUpper();
public string Icon => "images/UserGroups_96px.png";
private IPageViewModel _currentPageViewModel;
private ICommand _changePageCommand;
private ICommand _addCustomerCommand;
private ICommand _editCustomerCommand;
public SectionCustomersViewModel()
{
// Add available pages
CustomersViewModel = new CustomersViewModel();
CustomerViewModel = new CustomerViewModel();
CustomerToCustomerViewModel += (CustomerViewModel as CustomerViewModel).ReceiveCustomer;
// Set starting page
CurrentPageViewModel = CustomersViewModel;
}
#region Properties
#region Pages
public IPageViewModel CustomersViewModel { get; }
public IPageViewModel CustomerViewModel { get; }
#endregion
public IPageViewModel CurrentPageViewModel
{
get => _currentPageViewModel;
set
{
if (_currentPageViewModel != value)
{
_currentPageViewModel = value;
OnPropertyChanged("CurrentPageViewModel");
}
}
}
#endregion
#region Commands
public ICommand BackPageCommand
{
get
{
if (_changePageCommand == null)
_changePageCommand = new CommandHandler(p => ChangeViewModel(p as IPageViewModel), p => p is IPageViewModel);
return _changePageCommand;
}
}
public ICommand AddCustomerCommand
{
get
{
if (_addCustomerCommand == null)
_addCustomerCommand = new CommandHandler(param => AddCustomer());
return _addCustomerCommand;
}
}
public ICommand EditCustomerCommand
{
get
{
if (_editCustomerCommand == null)
_editCustomerCommand = new CommandHandler(c => EditCustomer(c as CustomerModel));
return _editCustomerCommand;
}
}
#endregion
#region Methods
private void ChangeViewModel(IPageViewModel viewModel)
=> CurrentPageViewModel = viewModel;
private void EditCustomer(CustomerModel customer)
{
CurrentPageViewModel = CustomerViewModel;
CustomerToCustomerViewModel?.Invoke(customer);
}
private void AddCustomer()
{
CurrentPageViewModel = CustomerViewModel;
CustomerToCustomerViewModel?.Invoke(new CustomerModel());
}
#endregion
}
View for the ViewModel A
<UserControl x:Class="Presentation.View.Customer.SectionCustomersView"
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:vm="clr-namespace:Presentation.ViewModel.Customer"
xmlns:v="clr-namespace:Presentation.View.Customer"
mc:Ignorable="d" d:DesignWidth="800" Height="Auto">
<UserControl.Resources>
<vm:SectionCustomersViewModel x:Key="SectionCustomersVM"/>
<DataTemplate DataType="{x:Type vm:CustomersViewModel}">
<v:CustomersView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:CustomerViewModel}">
<v:CustomerView />
</DataTemplate>
</UserControl.Resources>
<UserControl.DataContext>
<Binding Source="{StaticResource SectionCustomersVM}"/>
</UserControl.DataContext>
<Grid>
<ContentControl Content="{Binding CurrentPageViewModel}" />
</Grid>
ViewModel B (CustomerViewModel).
class CustomerViewModel : ObservableObject, IPageViewModel
{
#region Attributes
private CustomerModel _currentCustomer;
private AddressModel _currentAddress;
private ICommand _loadedCustomerCommand;
private ICommand _saveCustomerCommand;
#endregion
#region IPageViewModel's properties
public string Name => "Customer";
public string Icon => string.Empty;
#endregion
#region Properties
public Action<CustomerModel> ReceiveCustomer
=> SetCustomer;
public List<CountryModel> Countries => CountryModel.Load();
public List<ZoneModel> Zones => ZoneModel.Load();
public List<CustomerGroupModel> CustomerGroups => CustomerGroupModel.Load();
public CustomerModel CurrentCustomer
{
get => _currentCustomer;
set
{
if (value != _currentCustomer)
{
_currentCustomer = value;
OnPropertyChanged("CurrentCustomer");
}
}
}
public AddressModel CurrentAddress
{
get => _currentAddress;
set
{
if (value != _currentAddress)
{
_currentAddress = value;
OnPropertyChanged("CurrentAddress");
}
}
}
#endregion
#region Commands
public ICommand LoadedCommand
{
get
{
if (_loadedCustomerCommand == null)
_loadedCustomerCommand = new CommandHandler(o => LoadExtraData());
return _loadedCustomerCommand;
}
}
public ICommand SaveCommand
{
get
{
if (_saveCustomerCommand == null)
{
_saveCustomerCommand = new CommandHandler(
param => SaveCustomer(),
param => (CurrentCustomer != null)
);
}
return _saveCustomerCommand;
}
}
#endregion
#region Methods
private void SetCustomer(CustomerModel customer)
=> CurrentCustomer = customer;
private void LoadExtraData()
{
//if (CurrentCustomer.Address_id == 0)
// return;
//// Dummy data, just to test if the binding with the view is correctly setted.
//CurrentAddress = new AddressModel()
//{
// Firstname = "John",
// Lastname = "Doe",
// Address_1 = "Nowhere",
// City = "Somewhere",
// Company = "A-Z",
// Country_id = 1
//};
//// If the currentCustomer is setted here, it works fine.
//CurrentCustomer = new CustomerModel()
//{
// Firstname = "Some",
// Lastname = "One",
// Email = "somemail#mail.com",
// Telephone = "555-000-000",
// Status = true,
// Safe = false,
// Newsletter = false,
// Customer_group_id = 1
//};
}
private void SaveCustomer()
{
// You would implement your Product save here
CurrentAddress.Save();
CurrentCustomer.Save();
}
#endregion
}
View for the ViewModel B
<UserControl x:Class="Presentation.View.Customer.CustomerView"
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:vm="clr-namespace:Presentation.ViewModel.Customer"
xmlns:v="clr-namespace:Presentation.View.Customer"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
VerticalAlignment="Stretch"
VerticalContentAlignment="Stretch">
<UserControl.Resources>
<vm:CustomerViewModel x:Key="CustomerViewModel" />
</UserControl.Resources>
<UserControl.DataContext>
<Binding Source="{StaticResource CustomerViewModel}" />
</UserControl.DataContext>
<!-- Bind UserControl Loaded event to CustomersVM's LoadedCommand -->
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding LoadedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="160*" />
<RowDefinition Height="25*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="32" Height="32"
Command="{Binding DataContext.BackPageCommand, RelativeSource={RelativeSource AncestorType={x:Type v:SectionCustomersView}}}"
CommandParameter="{Binding DataContext.CustomersViewModel, RelativeSource={RelativeSource AncestorType={x:Type v:SectionCustomersView}}}">
<Image Source="/Presentation;Component/images/BackArrow_32px.png" Stretch="Uniform"/>
</Button>
<Label Grid.Row="0" Content="{Binding Name}" HorizontalAlignment="Left" VerticalAlignment="Top"
HorizontalContentAlignment="Right" VerticalContentAlignment="Center" Width="Auto" FontSize="24" FontFamily="Century Gothic" FontStretch="Expanded" BorderBrush="#FF4C4D5A" Height="37" Margin="67,10,0,0"/>
<Label Grid.Row="0" Content="{Binding Icon}" HorizontalAlignment="Left" VerticalAlignment="Top"
HorizontalContentAlignment="Left" VerticalContentAlignment="Bottom" Width="Auto" FontSize="16" FontFamily="Century Gothic" FontStretch="Expanded" Height="37" Margin="154,10,0,0" Foreground="#FF464646"/>
<Separator Grid.Row="0" Height="20" Margin="10,52,10,0" VerticalAlignment="Top"/>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto"
HorizontalContentAlignment="Center" VerticalContentAlignment="Top">
<WrapPanel>
<GroupBox Header="Detalles" FontFamily="Century gothic" Height="Auto" Width="367"
VerticalContentAlignment="Top" VerticalAlignment="Top">
<Grid Margin="0">
<StackPanel Orientation="Horizontal" Height="Auto"
VerticalAlignment="Top" Width="Auto" Margin="35,10,0,0">
<Label Grid.Row="1" Content="Firstname"
HorizontalAlignment="Left" VerticalAlignment="Center"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center" Width="auto" FontSize="16" FontFamily="Century Gothic" FontStretch="Expanded" Height="37" Foreground="#FF464646"/>
<TextBox HorizontalAlignment="Right" VerticalAlignment="Center"
VerticalContentAlignment="Center" HorizontalContentAlignment="Left"
Height="23" TextWrapping="NoWrap" Width="135"
Text="{Binding CurrentCustomer.Firstname}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Height="Auto"
VerticalAlignment="Top" Margin="35,52,0,0">
<Label Grid.Row="1" Content="Lastname"
HorizontalAlignment="Left" VerticalAlignment="Center"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center" Width="auto" FontSize="16" FontFamily="Century Gothic" FontStretch="Expanded" Height="37" Foreground="#FF464646"/>
<TextBox HorizontalAlignment="Right" VerticalAlignment="Center"
VerticalContentAlignment="Center" HorizontalContentAlignment="Left"
Height="23" TextWrapping="NoWrap" Width="135"
Text="{Binding CurrentCustomer.Lastname}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Height="Auto"
VerticalAlignment="Top" Margin="35,94,0,0">
<Label Grid.Row="1" Content="Email"
HorizontalAlignment="Left" VerticalAlignment="Center"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center" Width="auto" FontSize="16" FontFamily="Century Gothic" FontStretch="Expanded" Height="37" Foreground="#FF464646"/>
<TextBox HorizontalAlignment="Right" VerticalAlignment="Center"
VerticalContentAlignment="Center" HorizontalContentAlignment="Left"
Height="23" TextWrapping="NoWrap" Width="135"
Text="{Binding CurrentCustomer.Email}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Height="Auto"
VerticalAlignment="Top" Margin="35,136,0,0">
<Label Grid.Row="1" Content="Telephone"
HorizontalAlignment="Left" VerticalAlignment="Center"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center" Width="auto" FontSize="16" FontFamily="Century Gothic" FontStretch="Expanded" Height="37" Foreground="#FF464646"/>
<TextBox HorizontalAlignment="Right" VerticalAlignment="Center"
VerticalContentAlignment="Center" HorizontalContentAlignment="Left"
Height="23" TextWrapping="NoWrap" Width="135"
Text="{Binding CurrentCustomer.Telephone}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Height="Auto"
VerticalAlignment="Top" Margin="35,178,0,0">
<Label Grid.Row="1" Content="Customer Group"
HorizontalAlignment="Left" VerticalAlignment="Center"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center" Width="auto" FontSize="16" FontFamily="Century Gothic" FontStretch="Expanded" Height="37" Foreground="#FF464646"/>
<ComboBox HorizontalAlignment="Right" VerticalAlignment="Center"
VerticalContentAlignment="Center" HorizontalContentAlignment="Left"
Height="23" Width="135"
ItemsSource="{Binding CustomerGroups}"
SelectedValuePath="Customer_Group_ID" DisplayMemberPath="Name"
SelectedValue="{Binding CurrentCustomer.Customer_group_id}"/>
</StackPanel>
</Grid>
</GroupBox>
<GroupBox Header="Domicilio" FontFamily="Century gothic" Height="377" Width="376"
VerticalAlignment="Top" VerticalContentAlignment="Top">
<Grid Margin="0">
<StackPanel Orientation="Horizontal" Height="Auto"
VerticalAlignment="Top" Width="Auto" Margin="35,10,0,0">
<Label Grid.Row="1" Content="Name"
HorizontalAlignment="Left" VerticalAlignment="Center"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center" Width="auto" FontSize="16" FontFamily="Century Gothic" FontStretch="Expanded" Height="37" Foreground="#FF464646"/>
<TextBox HorizontalAlignment="Right" VerticalAlignment="Center"
VerticalContentAlignment="Center" HorizontalContentAlignment="Left"
Height="23" TextWrapping="NoWrap" Width="135"
Text="{Binding CurrentAddress.Firstname}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Height="Auto"
VerticalAlignment="Top" Margin="35,52,0,0">
<Label Grid.Row="1" Content="Lastname"
HorizontalAlignment="Left" VerticalAlignment="Center"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center" Width="auto" FontSize="16" FontFamily="Century Gothic" FontStretch="Expanded" Height="37" Foreground="#FF464646"/>
<TextBox HorizontalAlignment="Right" VerticalAlignment="Center"
VerticalContentAlignment="Center" HorizontalContentAlignment="Left"
Height="23" TextWrapping="NoWrap" Width="135"
Text="{Binding CurrentAddress.Lastname}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Height="Auto"
VerticalAlignment="Top" Margin="35,94,0,0">
<Label Grid.Row="1" Content="Company"
HorizontalAlignment="Left" VerticalAlignment="Center"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center" Width="auto" FontSize="16" FontFamily="Century Gothic" FontStretch="Expanded" Height="37" Foreground="#FF464646"/>
<TextBox HorizontalAlignment="Right" VerticalAlignment="Center"
VerticalContentAlignment="Center" HorizontalContentAlignment="Left"
Height="23" TextWrapping="NoWrap" Width="135"
Text="{Binding CurrentAddress.Company}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Height="Auto"
VerticalAlignment="Top" Margin="35,136,0,0">
<Label Grid.Row="1" Content="Address"
HorizontalAlignment="Left" VerticalAlignment="Center"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center" Width="auto" FontSize="16" FontFamily="Century Gothic" FontStretch="Expanded" Height="37" Foreground="#FF464646"/>
<TextBox HorizontalAlignment="Right" VerticalAlignment="Center"
VerticalContentAlignment="Center" HorizontalContentAlignment="Left"
Height="23" TextWrapping="NoWrap" Width="135"
Text="{Binding CurrentAddress.Address_1}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Height="Auto"
VerticalAlignment="Top" Margin="35,178,10,0">
<Label Content="Ciudad"
HorizontalAlignment="Left" VerticalAlignment="Center"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center" Width="auto" FontSize="16" FontFamily="Century Gothic" FontStretch="Expanded" Height="37" Foreground="#FF464646"/>
<TextBox HorizontalAlignment="Right" VerticalAlignment="Center"
VerticalContentAlignment="Center" HorizontalContentAlignment="Left"
Height="23" TextWrapping="NoWrap" Width="135"
Text="{Binding CurrentAddress.City}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Height="Auto"
VerticalAlignment="Top" Margin="35,220,10,0">
<Label Grid.Row="1" Content="Postcode"
HorizontalAlignment="Left" VerticalAlignment="Center"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center" Width="auto" FontSize="16" FontFamily="Century Gothic" FontStretch="Expanded" Height="37" Foreground="#FF464646"/>
<TextBox HorizontalAlignment="Right" VerticalAlignment="Center"
VerticalContentAlignment="Center" HorizontalContentAlignment="Left"
Height="23" TextWrapping="NoWrap" Width="135"
Text="{Binding CurrentAddress.Postcode}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Height="Auto"
VerticalAlignment="Top" Margin="35,262,0,0">
<Label Grid.Row="1" Content="Country"
HorizontalAlignment="Left" VerticalAlignment="Center"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center" Width="auto" FontSize="16" FontFamily="Century Gothic" FontStretch="Expanded" Height="37" Foreground="#FF464646"/>
<ComboBox HorizontalAlignment="Right" VerticalAlignment="Center"
VerticalContentAlignment="Center" HorizontalContentAlignment="Left"
Height="23" Width="135"
ItemsSource="{Binding Countries}"
DisplayMemberPath="Name" SelectedValuePath="Country_ID"
SelectedValue="{Binding CurrentAddress.Country_id}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Height="Auto"
VerticalAlignment="Top" Margin="35,304,10,-13">
<Label Grid.Row="1" Content="Region"
HorizontalAlignment="Left" VerticalAlignment="Center"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center" Width="auto" FontSize="16" FontFamily="Century Gothic" FontStretch="Expanded" Height="37" Foreground="#FF464646"/>
<ComboBox HorizontalAlignment="Right" VerticalAlignment="Center"
VerticalContentAlignment="Center" HorizontalContentAlignment="Left"
Height="23" Width="135" ItemsSource="{Binding Zones}"
DisplayMemberPath="Name" SelectedValuePath="Zone_ID"
SelectedValue="{Binding CurrentAddress.Zone_id}"/>
</StackPanel>
</Grid>
</GroupBox>
<GroupBox Header="Otro" FontFamily="Century gothic" Height="auto" Width="Auto"
VerticalAlignment="Top" VerticalContentAlignment="Top">
<Grid Margin="0">
<StackPanel Orientation="Vertical"
VerticalAlignment="Top" Margin="10">
<CheckBox HorizontalAlignment="Center" Style="{DynamicResource CheckBoxSlider}"
VerticalAlignment="Center" Content="Newsletter" FontSize="16" FontStretch="Expanded"
FontFamily="Century Gothic" Foreground="#FF464646" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" Width="255" Margin="30,8"
IsChecked="{Binding CurrentCustomer.Newsletter}"/>
<CheckBox HorizontalAlignment="Center" Style="{DynamicResource CheckBoxSlider}"
VerticalAlignment="Center" Content="Status" FontSize="16" FontStretch="Expanded"
FontFamily="Century Gothic" Foreground="#FF464646" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" Width="255" Margin="10,8"
IsChecked="{Binding CurrentCustomer.Status}"/>
<CheckBox HorizontalAlignment="Center" Style="{DynamicResource CheckBoxSlider}"
VerticalAlignment="Center" Content="Safe" FontSize="16" FontStretch="Expanded"
FontFamily="Century Gothic" Foreground="#FF464646" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" Width="255" Margin="10,8"
IsChecked="{Binding CurrentCustomer.Safe}"/>
</StackPanel>
</Grid>
</GroupBox>
</WrapPanel>
</ScrollViewer>
<Button Content="Accept" Grid.Row="2" Height="30"
VerticalAlignment="Bottom" HorizontalAlignment="Right"
Width="80" Margin="0,0,10,10"
Command="{Binding SaveCommand}"/>
</Grid>
Related
I have a grid of one player that looks like this: image
and here is the code:
<Grid HorizontalAlignment="Left" VerticalAlignment="Top" Margin="5" Background="AliceBlue">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Column="4" Grid.Row="0" FontWeight="Bold">Pool</Label>
<Label Grid.Column="5" Grid.Row="0" FontWeight="Bold">Edge</Label>
<Label Grid.ColumnSpan="2" Grid.Row="0" HorizontalAlignment="Center" FontWeight="Bold">Felix</Label>
<Label Grid.Column="0" Grid.Row="1">Might</Label>
<Button x:Name="btMightP1" Margin="3" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="3, 0, 3, 0" Click="btMightP1_Click">+</Button>
<TextBox x:Name="tbMight1" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="2" Grid.Column="2" Grid.Row="1" MinWidth="40">10</TextBox>
<Button x:Name="btMightM1" Margin="3" Grid.Column="3" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="4, 0, 4, 0" Click="btMightM1_Click">-</Button>
<TextBox Name="lbMightPool1" Grid.Row="1" Grid.Column="4" HorizontalAlignment="Center">0</TextBox>
<TextBox Name="lbMightEdge1" Grid.Row="1" Grid.Column="5" HorizontalAlignment="Center">0</TextBox>
<Label Grid.Column="0" Grid.Row="2">Speed</Label>
<Button x:Name="btSpeedP1" Margin="3" Grid.Column="1" Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="3, 0, 3, 0" Click="btSpeedP1_Click">+</Button>
<TextBox x:Name="tbSpeed1" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="2" Grid.Column="2" Grid.Row="2" MinWidth="40">10</TextBox>
<Button x:Name="btSpeedM1" Margin="3" Grid.Column="3" Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="4, 0, 4, 0" Click="btSpeedM1_Click">-</Button>
<TextBox Name="lbSpeedPool1" Grid.Row="2" Grid.Column="4" HorizontalAlignment="Center">0</TextBox>
<TextBox Name="lbSpeedEdge1" Grid.Row="2" Grid.Column="5" HorizontalAlignment="Center">0</TextBox>
<Label Grid.Column="0" Grid.Row="3">Intellect</Label>
<Button x:Name="btIntellectP1" Margin="3" Grid.Column="1" Grid.Row="3" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="3, 0, 3, 0" Click="btIntellectP1_Click">+</Button>
<TextBox x:Name="tbIntellect1" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="2" Grid.Column="2" Grid.Row="3" MinWidth="40">10</TextBox>
<Button x:Name="btIntellectM1" Margin="3" Grid.Column="3" Grid.Row="3" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="4, 0, 4, 0" Click="btIntellectM1_Click">-</Button>
<TextBox Name="lbIntellectPool1" Grid.Row="3" Grid.Column="4" HorizontalAlignment="Center">0</TextBox>
<TextBox Name="lbIntellectEdge1" Grid.Row="3" Grid.Column="5" HorizontalAlignment="Center">0</TextBox>
</Grid>
code for Player class:
public class Player
{
public DataClass Might { get; set; }
public DataClass Speed { get; set; }
public DataClass Intellect { get; set; }
public string Name { get; set; }
public Player()
{
Might = new DataClass();
Speed = new DataClass();
Intellect = new DataClass();
}
and DataClass:
public class DataClass
{
public string Current { get; set; }
public string Pool { get; set; }
public string Edge { get; set; }
public DataClass()
{
Current = "0";
Pool = "0";
Edge = "0";
}
}
My question is how can I create identical grid every time I create an object of Player and tie the TextBoxes with newly created object's properties? Is this achievable only using data binding? I've tried to use it but I don't quite understand how the binding works.
Use listbox or ItemsControl.
<Listbox ItemSource="{Binding YourListOfPlayers}">
<Listbox.ItemTemplate>
<DataTemplate>
<Put your common grid here/>
</DataTemplate>
</Listbox.ItemTemplate>
</Listbox>
<Page.Resources>
<ResourceDictionary>
<BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter" x:Name="testTest" />
</ResourceDictionary>
</Page.Resources>
itemscontrol:
<Grid Grid.Row="1" Grid.ColumnSpan="2" Name="testName">
<ScrollViewer VerticalScrollBarVisibility="Hidden" PanningMode="Both">
<ItemsControl ItemsSource="{Binding Path=NextMeetingList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Grid.Column="0" Grid.Row="0">
<Border x:Name = "myVariable" Grid.Column="0" Grid.Row="0" Margin="10" Height="30" Background="#A2C2E7" CornerRadius="5" BorderBrush="#A2C2E7">
<Grid Margin="8,0,8,0" Background="#A2C2E7">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Foreground="White" FontWeight="Bold" FontSize="15" Margin="0,4,0,0" HorizontalAlignment="Left">month</TextBlock>
<TextBlock Grid.Row="0" Grid.Column="1" Foreground="White" FontWeight="Bold" FontSize="15" Margin="0,4,0,0" HorizontalAlignment="Right">1 Meeting</TextBlock>
</Grid>
</Border>
<Border Grid.Column="0" Grid.Row="0" Margin="10" Height="60" Background="GhostWhite" CornerRadius="3" BorderBrush="{Binding BorderColor}" BorderThickness="0,8,0,0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="118"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" FontSize="40" Margin="10,5,0,0" Style="{DynamicResource Lato-Semibold}" Text="{Binding endDate.Day}"/>
<TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" FontSize="12" Margin="77,13,0,0" Height="Auto" Style="{DynamicResource Lato-Semibold}" Text="{Binding DayString}"/>
<TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" FontSize="14" Margin="70,26,0,0" Height="Auto" Style="{DynamicResource Lato-Semibold}" Text="{Binding endDate.Hour}"/>
<TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" FontSize="14" Margin="86,26,0,0" Height="Auto" Style="{DynamicResource Lato-Semibold}" Text=":"/>
<TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" FontSize="14" Margin="90,26,0,0" Height="Auto" Style="{DynamicResource Lato-Semibold}" Text="{Binding MinuteString}"/>
<Border Grid.Row="0" Grid.Column="0" Width="1" BorderBrush="#BABABA" Height="40" Margin="115,-6,0,0" BorderThickness="1" HorizontalAlignment="Left"></Border>
<TextBlock Grid.Row="0" Grid.Column="1" HorizontalAlignment="Left" Text="{Binding subject}" FontWeight="Bold" FontSize="17" Margin="10,10,0,0"/>
<TextBlock Grid.Row="0" Grid.Column="1" Width="Auto" TextWrapping="Wrap" HorizontalAlignment="Left" Text="{Binding descr}" FontSize="10" Margin="20,27,150,0"/>
<TextBlock Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Text="{Binding companyName}" FontSize="10" Margin="0,10,30,0"/>
<TextBlock Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Text="sala del consiglio" FontSize="10" Margin="0,27,30,0"/>
<TextBlock Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Text=">" FontSize="15" VerticalAlignment="Center" Margin="0,-5,10,0"/>
</Grid>
</Border>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
Hello everyone , I should be able to make a grid Collapsed inside a ItemsControl in WPF .
The problem is that I can not understand how to use the booleanToVisibilityConverter from code behind .
Maybe I'm missing out on a glass of water but I can not connect how to do, if the name TestTest septum can not see it then the code-behind .
from code behind i don't see "myVariable"
To get hold of the converter from code-behind, you'd have to look it up in the Page's Resources dictionary. Do something like this in your Page class:
IValueConverter converter = this.Resources["booleanToVisibilityConverter"] as IValueConverter;
Giving the converter's resource entry a Name is not necessary; here you want to use the Key. Also, converters are normally used with XAML bindings -- if you want one in code, you can just instantiate one:
IValueConverter converter = new BooleanToVisibilityConverter();
Common usage goes something like this:
<Window.Resources>
<ResourceDictionary>
<BooleanToVisibilityConverter x:Key="Converter" />
</ResourceDictionary>
</Window.Resources>
<Grid Visibility="{Binding Display, Converter={StaticResource Converter}}">
...
</Grid>
Code-behind, using the window class itself as the data context:
public partial class MainWindow
{
public bool Display { get; set; };
public MainWindow()
{
InitializeComponent();
DataContext = this; // For the binding
Display = true;
}
}
Okay, one more, this time without data binding or converter:
<Grid x:Name="myGrid">
...
</Grid>
Code-behind:
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
myGrid.Visibility = Visibility.Visible;
}
}
The above doesn't explain why the OP couldn't reference "myVariable" from code-behind. That's because it's in a template, which is instantiated (dynamically) once per item in the collection.
It's still possible to get at it from code -- dynamically. For example, this XAML uses a DataTemplate:
<ItemsControl ItemsSource="{Binding Names}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid x:Name="innerGrid" Loaded="OnGridLoaded" DataContext="{Binding Name, Mode=OneWay}">
<TextBox Text="{Binding Path=., Mode=OneWay}" />
</Grid>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The following code-behind lets us reach into the template and make "innerGrid" disappear selectively:
public class Data
{
public string Name { get; }
public Data(string name)
{
Name = name;
}
}
public partial class MainWindow
{
public Data[] Names { get; } = { new Data("Hello"), new Data("World") };
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private void OnGridLoaded(object sender, RoutedEventArgs e)
{
Grid outerGrid = sender as Grid;
Grid innerGrid = outerGrid?.FindName("innerGrid") as Grid;
if (innerGrid != null)
{
string name = innerGrid.DataContext as string;
if (name == "Hello")
{
innerGrid.Visibility = Visibility.Collapsed;
}
}
}
}
(To make the string easily accessible I bound the Data object to the "innerGrid" DataContext.)
I am using LongListSelector and trying to bind an array. But no data is getting displayed. Following is my code please let me know what i am doing wrong?
XAML
<phone:LongListSelector Name="peopleLongListSelector"
ItemsSource="{Binding ComponentData}"
GroupHeaderTemplate="{StaticResource LongListSelectorGroupHeaderTemmplate}"
ItemTemplate="{StaticResource LongListSelectorItemTemplate}"
HideEmptyGroups ="true"
IsGroupingEnabled ="true"
LayoutMode="List">
</phone:LongListSelector>
<DataTemplate x:Key="LongListSelectorGroupHeaderTemmplate">
<Border Background="Transparent" Padding="5">
<Border Background="{StaticResource PhoneAccentBrush}" BorderBrush="{StaticResource PhoneAccentBrush}" BorderThickness="2"
Width="62" Height="62" Margin="0,0,18,0"
HorizontalAlignment="Left">
<TextBlock Text="{Binding Name}"
Foreground="{StaticResource PhoneForegroundBrush}"
FontSize="48"
Padding="6"
FontFamily="{StaticResource PhoneFontFamilySemiLight}"
HorizontalAlignment="Left"
VerticalAlignment="Center"/>
</Border>
</Border>
</DataTemplate>
<DataTemplate x:Key="LongListSelectorItemTemplate">
<StackPanel Orientation="Horizontal" Margin="4,4">
<Image Width="62" Height="62" Source="{Binding Image}" VerticalAlignment="Top" Margin="0,0,15,0"/>
<TextBlock Text="{Binding Name}" Style="{StaticResource PhoneTextLargeStyle}" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</StackPanel>
</DataTemplate>
C#
public class Component
{
public string Guid {get; set;}
public string Name{get; set;}
public Item[] Items{get; set;}
}
public class Item
{
public string Title{get; set;}
public string Subtitle{get; set;}
public string Date{get; set;}
}
public class MainLstViewModel : BaseViewModel
{
private Component[] ComponentData;
public MainLstViewModel()
{
ComponentData = Proxy.GetDataAsync();
}
}
You have some attributes in your Class and binding different in xaml
<phone:LongListSelector Name="peopleLongListSelector"
ItemsSource="{Binding ComponentData}"
GroupHeaderTemplate="{StaticResource LongListSelectorGroupHeaderTemmplate}"
ItemTemplate="{StaticResource LongListSelectorItemTemplate}"
HideEmptyGroups ="true"
IsGroupingEnabled ="true"
LayoutMode="List">
</phone:LongListSelector>
<DataTemplate x:Key="LongListSelectorGroupHeaderTemmplate">
<Border Background="Transparent" Padding="5">
<Border Background="{StaticResource PhoneAccentBrush}" BorderBrush="{StaticResource PhoneAccentBrush}" BorderThickness="2"
Width="62" Height="62" Margin="0,0,18,0"
HorizontalAlignment="Left">
<TextBlock Text="{Binding Name}"
Foreground="{StaticResource PhoneForegroundBrush}"
FontSize="48"
Padding="6"
FontFamily="{StaticResource PhoneFontFamilySemiLight}"
HorizontalAlignment="Left"
VerticalAlignment="Center"/>
</Border>
</Border>
</DataTemplate>
<DataTemplate x:Key="LongListSelectorItemTemplate">
<StackPanel Orientation="Horizontal" Margin="4,4">
<TextBlock Text="{Binding Name}" Style="{StaticResource PhoneTextLargeStyle}" VerticalAlignment="Center" HorizontalAlignment="Left"/>
<TextBlock Text="{Binding Subtitle}" Style="{StaticResource PhoneTextLargeStyle}" VerticalAlignment="Center" HorizontalAlignment="Left"/>
<TextBlock Text="{Binding Date}" Style="{StaticResource PhoneTextLargeStyle}" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</StackPanel>
</DataTemplate>
I have a Pivot view in my WP8 app, and I'm trying to access the data collection from the view's class upon Click event "removePin".
The source of the data collection is another class called Pins.
how can I achieve that?
this is my snippet code for the XAML for that particular part
<phone:PivotItem Header="Pins">
<!-- Content Panel -->
<Grid x:Name="ContentPanel2" HorizontalAlignment="Left" Height="583" Margin="10,10,0,0" Grid.Row="1" VerticalAlignment="Top" Width="460">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="400*"/>
<ColumnDefinition Width="0*"/>
<ColumnDefinition Width="87*"/>
</Grid.ColumnDefinitions>
<ListBox x:Name="lstData2" ItemsSource="{Binding DataCollection2, Source={StaticResource PinsCollection}}"
Grid.ColumnSpan="3" Foreground="#FF1D53D0" Height="583" VerticalAlignment="Bottom">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Tap="StackPanel_Tap">
<Image Margin="8" VerticalAlignment="Top" Source="{Binding ImageUri}"
Width="100" Height="100" />
<StackPanel Height="93" Width="259" >
<TextBlock Margin="8" Width="250" TextWrapping="Wrap" VerticalAlignment="Top" HorizontalAlignment="Left" Foreground="#FF1D53D0"
Text="{Binding Pinnedname}" Height="33" RenderTransformOrigin="0.5,0.5" FontFamily="Segoe WP SemiLight" FontSize="24" FontWeight="Bold" />
<TextBlock Width="155" Margin="8,0,8,8" VerticalAlignment="Top"
HorizontalAlignment="Left" Text="{Binding Status}" Foreground="#FF1D53D0" FontFamily="Segoe WP SemiLight" />
</StackPanel>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="Remove Pin" Click="RemovePin_Click" Tag="{Binding pinId}"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<!-- End of Content Panel -->
</Grid>
Create a custom command class:
public class CustomCommand : ICommand
{
Action _exec;
public CustomCommand(Action exec)
{
_exec = exec;
}
public void Execute(object parameter)
{
if (_exec != null) _exec();
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
}
Add it to the view model for elements of pins collection (I supposed it's PinItem)
public CustomCommand RemovePinCommand
{
get { return (CustomCommand)GetValue(RemovePinCommandProperty); }
set { SetValue(RemovePinCommandProperty, value); }
}
public static readonly DependencyProperty RemovePinCommandProperty =
DependencyProperty.Register("RemovePinCommand",
typeof(CustomCommand),
typeof(PinItem),
new UIPropertyMetadata(null));
In the constructor of that class implement your logic for this command:
RemovePinCommand = new CustomCommand(() =>
{
//delete this pin from its parent collection
});
final step is to bind the command to the menu item:
<toolkit:MenuItem Header="Remove Pin" Command="{Binding RemovePinCommand}"/>
I have the following code. It builds and runs but does not populate the listbox. Can someone spot the mistake?
<Grid>
<ListBox ItemsSource="{Binding Path=questions}" Height="401" HorizontalAlignment="Left" Name="results" VerticalAlignment="Top" Width="260" Margin="0,20,0,0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=question.votes}" FontSize="15" Padding="5" Background="White" Foreground="Black"/>
<TextBlock Text="{Binding Path=question.answers}" FontSize="15" Padding="5" Background="White" Foreground="Black"/>
</StackPanel>
<StackPanel Orientation="Vertical" Height="Auto" Width="249">
<TextBlock Text="{Binding Path=question.title}" FontWeight="Bold" Background="#FF92F2CD" Height="22" Width="229" Foreground="Black"/>
<TextBlock Text="{Binding Path=question.body}" TextWrapping="Wrap" Height="43" Width="231" Background="#FFEFEFEF" Foreground="Black"/>
</StackPanel>
</StackPanel>
<StackPanel>
<TextBlock Text="{Binding Path=question.tags}" Foreground="#FFFF9C00" Background="#FF4E3D3D" FontWeight="Bold" TextAlignment="Center"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="Refresh" Height="22" HorizontalAlignment="Left" Name="button1" VerticalAlignment="Top" Width="54" />
</Grid>
public class question
{
public string votes { get; set; }
public string answers { get; set; }
public string title { get; set; }
public string body { get; set; }
public string tags { get; set; }
}
public partial class MainWindow : Window
{
ObservableCollection<question> questions = new ObservableCollection<question>();
public MainWindow()
{
questions.Add(new question
{
votes = "2",
answers = "3",
title = "This is a sample title",
body = "This is a sample body text. It should wrap and not look like shit when presented.",
tags = "C#,WPF,XML,JediStyle"
});
this.DataContext = this;
InitializeComponent();
}
}
Binding does not work on fields but on properties.
ObservableCollection<question> questions = new ObservableCollection<question>();
ObservableCollection<question> MyQuestions
{
get { return questions; }
}
And in XAML
ItemsSource="{Binding Path=MyQuestions}"
You also don't have to specify question as a part of path for every binding within particular list item:
Text="{Binding Path=question.tags}" should be Text="{Binding Path=tags}" or even simpler: Text="{Binding tags}"
<ListBox ItemsSource="{Binding Path=questions}" Height="401" HorizontalAlignment="Left" Name="results" VerticalAlignment="Top" Width="260" Margin="0,20,0,0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=votes}" FontSize="15" Padding="5" Background="White" Foreground="Black"/>
<TextBlock Text="{Binding Path=answers}" FontSize="15" Padding="5" Background="White" Foreground="Black"/>
</StackPanel>
<StackPanel Orientation="Vertical" Height="Auto" Width="249">
<TextBlock Text="{Binding Path=title}" FontWeight="Bold" Background="#FF92F2CD" Height="22" Width="229" Foreground="Black"/>
<TextBlock Text="{Binding Path=body}" TextWrapping="Wrap" Height="43" Width="231" Background="#FFEFEFEF" Foreground="Black"/>
</StackPanel>
</StackPanel>
<StackPanel>
<TextBlock Text="{Binding Path=tags}" //am not sure from where this tags coming
Foreground="#FFFF9C00" Background="#FF4E3D3D" FontWeight="Bold" TextAlignment="Center"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I would try to use a ViewModel ...
Good Article
Another Good Article
The two articles highlight the benefits of full binding and go into the NotifyPropertyChanged and commands. Worth a read.