Trying to understand MVVM Data keeps resetting - c#

Goal: When I enter a value in the textbox for Technician Name: I want it to update inside the DataModel and when I click to the NewCallView it will display inside the newcall View and when I click back to the DefaultViewModel it will appear still entered.
Problem: When i change between views the data resets.
I am going to provide my full code in an effort to figure out why my data keeps resetting. - I am still learning MVVM this is my first crack at it. I would normally make a 1 page application using code-behind. I am finding it hard to link up my Model to my ViewModels, and maybe I am calling (getting/setting) the properties incorrectly.
With regards to the code behind for each of my Views I did not alter it at all from its creation, I only worked in the Xaml.
Mainwindow codebehind
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using callFlow.ViewModels;
using callFlow.Models;
namespace callFlow
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void DefaultViewClicked(object sender, RoutedEventArgs e)
{
DataContext = new DefaultViewModel();
}
private void NewCallClicked(object sender, RoutedEventArgs e)
{
DataContext = new NewCallViewModel();
}
}
}
Main Window View / wpf
<Window x:Class="callFlow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:callFlow"
xmlns:viewmodels="clr-namespace:callFlow.ViewModels"
xmlns:views="clr-namespace:callFlow.Views"
mc:Ignorable="d"
Title="Call FLow Management" Height="728" Width="1260">
<Window.Resources>
<DataTemplate x:Name="defaultViewTemplate" DataType="{x:Type viewmodels:DefaultViewModel}">
<views:DefaultView DataContext="{Binding}"/>
</DataTemplate>
<DataTemplate x:Name="newCallViewTemplate" DataType="{x:Type viewmodels:NewCallViewModel}">
<views:NewCallView DataContext="{Binding}"/>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="5" Grid.RowSpan="6" Background="
{DynamicResource {x:Static SystemColors.MenuBrushKey}}"/>
<Grid Grid.Row="1" Grid.Column="0" Grid.RowSpan="6" />
<Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="6" Background="FloralWhite">
<Image Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Source="/BofA2.png" Width="400"
HorizontalAlignment="Left" />
<Border BorderThickness="1" BorderBrush="Black" Grid.Column="0" Grid.Row="0"
Grid.ColumnSpan="6" CornerRadius="8 8 8 8"/>
<Border BorderThickness="1" BorderBrush="Black" Grid.Column="0" Grid.Row="1"
Grid.RowSpan="6"
CornerRadius="8 8 8 8"/>
</Grid>
<StackPanel Grid.Row="1" Grid.Column="0" Grid.RowSpan="6">
<Button Name="loadDefaultView" Content="Home" Grid.Column="2" Grid.Row="2" Height="40"
Margin="5 5 5 5" Click="DefaultViewClicked" > </Button>
<Button Name="loadNewCall" Content="New Call" Grid.Column="2" Grid.Row="2" Height="40"
Margin="5 0 5 0 " Click="NewCallClicked" ></Button>
</StackPanel>
<ContentControl Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="6" Grid.RowSpan="6" Content="
{Binding}">
</ContentControl>
</Grid>
</Window>
Views/DefaultView.xaml
<UserControl x:Class="callFlow.Views.DefaultView"
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:callFlow.Views"
xmlns:viewmodels="clr-namespace:callFlow.ViewModels"
xmlns:model="clr-namespace:callFlow.Models"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="FloralWhite">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.ColumnSpan="7" Margin="0 10 0 0" HorizontalAlignment="Center"
Text="Call Flow Management" TextWrapping="Wrap" FontSize="24" VerticalAlignment="Top"/>
<StackPanel Grid.Row="0" Grid.Column="5" Grid.ColumnSpan="1" Margin="0 5 0 0">
<TextBlock HorizontalAlignment="Left" Grid.Column="0" Grid.Row="1" Text="Technician Name: "
FontSize="14" TextWrapping="Wrap" Grid.ColumnSpan="2" Width="134"/>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="6" Grid.ColumnSpan="1" Margin="5 5 5 0">
<TextBox Name="techName" Text="{Binding SelectedModel.TechName,Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" BorderBrush="#FF4A5780" Grid.RowSpan="2" />
</StackPanel>
<TextBlock x:Name="TextUpdate" Grid.Column="5" HorizontalAlignment="Left" Margin="41,0,0,0"
Grid.Row="1" Text="{Binding SelectedModel.TechName}" TextWrapping="Wrap" VerticalAlignment="Center"/>
</Grid>
</UserControl>
ViewModels/DefaultViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using callFlow.Models;
namespace callFlow.ViewModels
{
public class DefaultViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public DefaultViewModel() { }
private ObservableCollection<DataModel> model = new ObservableCollection<DataModel>();
private DataModel _SelectedModel;
public DataModel SelectedModel
{
get { return _SelectedModel ?? (_SelectedModel = new DataModel()); }
set { _SelectedModel = value; OnPropertyChanged(); }
}
public void changeSelectedModel(DataModel newSelectedModel)
{
SelectedModel.TechName = newSelectedModel.TechName;
}
private void OnPropertyChanged([CallerMemberName] string techName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(techName));
}
}
}
Views\NewCallView.xaml
<UserControl x:Class="callFlow.Views.NewCallView"
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:callFlow.Views"
xmlns:viewmodels="clr-namespace:callFlow.ViewModels"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="#FFFDFDFD">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock x:Name="techNameSet" Grid.Column="2" HorizontalAlignment="Left" Margin="40,52,0,0"
Grid.Row="2" Text="{Binding SelectedModel.TechName}" TextWrapping="Wrap" VerticalAlignment="Top"
Grid.ColumnSpan="2" Width="114"/>
</Grid>
</UserControl>
NewCallViewModel.cs
namespace callFlow.ViewModels
{
class NewCallViewModel
{
//It's empty, my view is calling SelectedModel.TechName from DataViewModel which works when I update the DataModel Directly
}
}
Last but not least!!!!
Models/DataModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using System.Drawing;
namespace callFlow.Models
{
public class DataModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string techName;
public DataModel()
{
}
public string TechName
{
get { return techName; }
set { techName = value; OnPropertyChanged(); }
}
private void OnPropertyChanged([CallerMemberName] string techName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(techName));
}
}
}

Related

WPF bind TextBlock "text" in one user control to textbox in another UserControl Where both of them are hosted in a Frame inside mainWindow

SUMMARY OF THE PROBLEM:
I have main window which has a frame and a button, in the frame i'm going to show one user control at a time (i provided an image of my usercontrol).
in the first UserControl, i will write 4 player names (two for each team).
after i press the button and i go to next usercontrol i want to show the names of the players in textblock. I also want to bind IsChecked property of radio button in first UserControl to the second UserControl. (i have other buttons that show up in mainWindow depends on what usercontrol is in the Frame right Now)
WHAT I TRIED:
I tried binding the textbox property to the textblock in the second usercontrol but it doesnt show or i cant access it.
because i have the button in the mainWindow i tried saving the names in variable then pass it to next usercontrol but didnt work also.
Also tried alot of random online solution i found online but nothing worked.
i need a way to expose the property of First UserControl to be used in the Second UserControl
MY CODE
MainWindow xaml
<Grid SnapsToDevicePixels="True" x:Name="myGrid" >
<Grid.Background>
<ImageBrush x:Name="myBackground" ImageSource="background1.png" Stretch="UniformToFill"/>
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="300" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="*" />
<RowDefinition Height=" auto" />
<RowDefinition Height=" 20" />
</Grid.RowDefinitions>
<Frame x:Name="Main" Grid.Row="0" Grid.RowSpan="2" Grid.Column="0" Grid.ColumnSpan="5" NavigationUIVisibility="Hidden" >
</Frame>
<Button Style="{StaticResource StandardButton}" Visibility="Visible" x:Name="playersBtn" Grid.Column="2" Grid.Row ="2" Margin="100,40,100,40" FontSize="36" Content="إبدأ" FontFamily="Ara Hamah Homs" Padding="50,0" Background="#FFFFE900" Click="playerInfoBtn" BorderBrush="{x:Null}" Foreground="Black" >
</Button>
MainWindow c#
namespace Try3
{
public partial class MainWindow : Window
{
SoundPlayer MP = new SoundPlayer();
public MainWindow()
{
InitializeComponent();
MP.SoundLocation = "C:/Users/eadh2/Desktop/game tries/try3/try3/sound1.wav";
MP.PlayLooping();
}
private void playerInfoBtn(object sender, RoutedEventArgs e)
{
Main.Content = new PlayersInfoPage();
playersBtn.Visibility = Visibility.Hidden;
startBtn.Visibility = Visibility.Visible;
icon.Visibility = Visibility.Collapsed;
ImageBrush b = new ImageBrush();
b.ImageSource = new BitmapImage(new Uri("pack://application:,,,/background flat.png"));
myGrid.Background = b;
}
private void startBtn_Click(object sender, RoutedEventArgs e)
{
Main.Content = new gamePage();
startBtn.Visibility = Visibility.Collapsed;
gamePageBoarder.Visibility = Visibility.Visible;
}
private void startBtn_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
startBtn.Background = Brushes.DarkGreen;
}
}
}
First usercontrol xaml to enter player names (Image of First UserControl to enter player names)
<UserControl x:Class="Try3.PlayersInfoPage"
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:Try3"
mc:Ignorable="d"
d:DesignHeight="862.179" d:DesignWidth="1210.632" >
<Grid SnapsToDevicePixels="True">
<Grid.ColumnDefinitions >
<ColumnDefinition Width="150" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width=" *" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="AUTO" />
<ColumnDefinition Width="150" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height=" *" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="2" Text="بيانات الفريق الأحمر" FontSize="36" Margin="50,0,50,0" FontFamily="Ara Hamah Homs" />
<TextBox x:Name="redFirst" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Margin="0,30,0,20" Padding="10" FontSize="36" HorizontalContentAlignment="Center" Text="اللاعب الأول" Foreground="#FF919191" GotMouseCapture="redFirst_GotMouseCapture" FontFamily="Ara Hamah Homs" />
<TextBox x:Name="redSecond" Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" Margin="0,30,0,110" Padding="10" FontSize="36" HorizontalContentAlignment="Center" Text="اللاعب الثاني" Foreground="#FF919191" GotMouseCapture="redSecond_GotMouseCapture1" FontFamily="Ara Hamah Homs" />
<TextBlock Grid.Column="4" Grid.Row="1" Grid.ColumnSpan="2" Text="بيانات الفريق الأخضر " FontSize="36" Margin="50,0,50,20" FontFamily="Ara Hamah Homs" />
<TextBox x:Name="greenFirst" Grid.Row="2" Grid.Column="4" Grid.ColumnSpan="2" Margin="0,30,0,20" Padding="10" FontSize="36" HorizontalContentAlignment="Center" Text="اللاعب الأول" Foreground="#FF919191" GotMouseCapture="greenFirst_GotMouseCapture2" FontFamily="Ara Hamah Homs" />
<TextBox x:Name="greenSecond" Grid.Row="3" Grid.Column="4" Grid.ColumnSpan="2" Margin="0,30,0,110" Padding="10" FontSize="36" HorizontalContentAlignment="Center" Text="اللاعب الثاني" Foreground="#FF919191" GotMouseCapture="greenSecond_GotMouseCapture3" FontFamily="Ara Hamah Homs" />
<Border x:Name="roundsBoarder" Grid.Column="3" Grid.Row="2" Grid.RowSpan="2" BorderThickness ="3" BorderBrush="Black" CornerRadius="0" Margin="20,50,20,130" MaxHeight="170" MaxWidth="350" VerticalAlignment="Center" Background="#99FFFFFF" MouseEnter="Border_MouseEnter" MouseLeave="roundsBoarder_MouseLeave">
<StackPanel HorizontalAlignment="Center" >
<StackPanel Orientation="Horizontal" >
<Viewbox Height="40" Width="40" >
<RadioButton BorderBrush="#FFFFE900" VerticalContentAlignment="Center" HorizontalAlignment="Left" GroupName="roundsNumber" FontFamily="Ara Hamah Homs" FontSize="12"/>
</Viewbox>
<TextBlock Text="جولة" FontSize="42" Margin="20,0,0,0" FontFamily="Alnaqaaa R" />
</StackPanel>
<StackPanel Orientation="Horizontal" >
<Viewbox Height="40" Width="40" >
<RadioButton BorderBrush="#FFFFE900" VerticalContentAlignment="Center" HorizontalAlignment="Left" GroupName="roundsNumber" FontFamily="Ara Hamah Homs" FontSize="12"/>
</Viewbox>
<TextBlock Text="ثلاث جولات" FontSize="42" Margin="20,0,0,0" FontFamily="Alnaqaaa R" />
</StackPanel>
</StackPanel>
</Border>
</Grid>
First UserControl C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Try3
{
public partial class PlayersInfoPage : UserControl
{
public PlayersInfoPage()
{
InitializeComponent();
}
private void redFirst_GotMouseCapture(object sender, MouseEventArgs e)
{
redFirst.Text = "";
redFirst.Foreground = Brushes.Black;
}
private void redSecond_GotMouseCapture1(object sender, MouseEventArgs e)
{
redSecond.Text = "";
redSecond.Foreground = Brushes.Black;
}
private void greenFirst_GotMouseCapture2(object sender, MouseEventArgs e)
{
greenFirst.Text = "";
greenFirst.Foreground = Brushes.Black;
}
private void greenSecond_GotMouseCapture3(object sender, MouseEventArgs e)
{
greenSecond.Text = "";
greenSecond.Foreground = Brushes.Black;
}
private void Save_MouseEnter(object sender, MouseEventArgs e)
{
}
private void Save_MouseLeave(object sender, MouseEventArgs e)
{
}
private void Border_MouseEnter(object sender, MouseEventArgs e)
{
roundsBoarder.Background = new SolidColorBrush(Colors.White) { Opacity = 1 };
roundsBoarder.CornerRadius = new CornerRadius(20);
}
private void roundsBoarder_MouseLeave(object sender, MouseEventArgs e)
{
roundsBoarder.Background = new SolidColorBrush(Colors.White) { Opacity = 0.6 };
roundsBoarder.CornerRadius = new CornerRadius(0);
}
}
}
Second UserControl xaml to show player names in each side
<UserControl x:Class="Try3.gamePage"
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:try3"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.ColumnDefinitions >
<ColumnDefinition Width="50" />
<ColumnDefinition Width="60" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="60" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions >
<RowDefinition Height="50" />
<RowDefinition Height="*" />
<RowDefinition Height="auto" />
<RowDefinition Height="50" />
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<StackPanel Orientation="Vertical" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="1" >
<TextBlock HorizontalAlignment="Center" FontSize="36" FontFamily="Ara Hamah Homs" Text="الفريق الأحمر" />
<TextBlock x:Name="redFirstPlayer" FontSize="24" FontFamily="Ara Hamah Homs" Text="اللاعب الاول" HorizontalAlignment="Center"/>
<TextBlock x:Name="redSecondPlayer" FontSize="24" FontFamily="Ara Hamah Homs" Text="اللاعب الثاني" HorizontalAlignment="Center"/>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Column="6" Grid.ColumnSpan="2" Grid.Row="1">
<TextBlock FontSize="36" FontFamily="Ara Hamah Homs" Text="الفريق الأخضر" HorizontalAlignment="Center" Margin="0,0,0,20"/>
<TextBlock x:Name="greenFirstPlayer" FontSize="24" FontFamily="Ara Hamah Homs" Text="اللاعب الاول" HorizontalAlignment="Center"/>
<TextBlock x:Name="greenSecondPlayer" FontSize="24" FontFamily="Ara Hamah Homs" Text="اللاعب الثاني" HorizontalAlignment="Center"/>
</StackPanel>
<TextBlock x:Name="redScore" Grid.Column="1" Grid.Row="3" FontSize="42" FontFamily="Ara Hamah Homs" Text="0" HorizontalAlignment="center" />
<Image Source="trophy (1).png" Grid.Column="2" Grid.Row="3" HorizontalAlignment="Left"/>
<TextBlock x:Name="greenScore" Grid.Column="7" Grid.Row="3" FontSize="42" FontFamily="Ara Hamah Homs" HorizontalAlignment="center" Text="0" />
<Image Source="trophy (1).png" Grid.Column="6" Grid.Row="3" HorizontalAlignment="Right"/>
<StackPanel Grid.Row="1" Grid.Column="6" Grid.ColumnSpan="2" Margin="0,50,0,0" >
</StackPanel>
</Grid>

WPF Xceed Wizard Event in Next button

I'm creating a Wizard to export DB tables into CSV.
I'm using Xceed Wizard and I need an Event in Next button. I want to validate the parameters before going to the next page when I click "Next", but I only can set CanSelectNextPage.
XAML code:
<xctk:WizardPage x:Name="PageBD1" PageType="Interior"
Title="{DynamicResource PageBD1Title}"
Description="{DynamicResource PageBD1Desc}"
NextPage="{Binding ElementName=PageBD2}"
PreviousPage="{Binding ElementName=Page1}"
CanSelectNextPage="False">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock x:Name="tbBDInfoServer1" Text="{DynamicResource tbBDInfoServer1}" Grid.Row="0" Grid.Column="0" />
<TextBox x:Name="tbBDServer1" Grid.Row="0" Grid.Column="2" TextChanged="tbBD1_TextChanged"/>
<TextBlock x:Name="tbBDInfoName1" Text="{DynamicResource tbBDInfoName1}" Grid.Row="1" Grid.Column="0" Margin="0,10,0,0" />
<TextBox x:Name="tbBDName1" Grid.Row="1" Grid.Column="2" Margin="0,10,0,0" TextChanged="tbBD1_TextChanged"/>
<TextBlock x:Name="tbBDInfoUser1" Text="{DynamicResource tbBDInfoUser1}" Grid.Row="2" Grid.Column="0" Margin="0,10,0,0" />
<TextBox x:Name="tbBDUser1" Grid.Row="2" Grid.Column="2" Margin="0,10,0,0" TextChanged="tbBD1_TextChanged"/>
<TextBlock x:Name="tbBDInfoPwd1" Text="{DynamicResource tbBDInfoPwd1}" Grid.Row="3" Grid.Column="0" Margin="0,10,0,0" />
<PasswordBox x:Name="tbBDPwd1" Grid.Row="3" Grid.Column="2" Margin="0,10,0,0"/>
</Grid>
</xctk:WizardPage>
C# code:
private void tbBD1_TextChanged(object sender, TextChangedEventArgs e)
{
if (tbBDServer1.Text != "" && tbBDName1.Text != "" && tbBDUser1.Text != "")
{
PageBD1.CanSelectNextPage = true;
}
else
PageBD1.CanSelectNextPage = false;
}
Thanks.

Xamarin : Adding multiple bindings to multiple collection views on the same page

I am currently trying to build two separate collection views on the same page in Xamarin. I keep getting the error that content is set more than once and also that I've set the content binding more than once. How do I add different bindings to two separate collection views on the same page?
ConsumerOrders.xaml page:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:viewmodels="clr-namespace:Shared.ViewModel"
mc:Ignorable="d"
x:Class="Shared.consumerOrders">
<ContentPage.BindingContext>
<viewmodels:AddedServicesViewModel />
</ContentPage.BindingContext>
<d:ContentPage.BindingContext>
<viewmodels:PastOrderViewModel />
</d:ContentPage.BindingContext>
<ScrollView>
<CollectionView ItemsSource="{Binding ViewAddedServices}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="4"/>
<!--0-->
<RowDefinition Height="30"/>
<!--1-->
<RowDefinition Height="20"/>
<!--2-->
<RowDefinition Height=".25"/>
<!--3-->
<RowDefinition Height="4"/>
<!--4-->
<RowDefinition Height="Auto"/>
<!--5-->
<RowDefinition Height="Auto"/>
<!--6-->
<RowDefinition Height=".25"/>
<!--7-->
<RowDefinition Height="Auto"/>
<!--8-->
<RowDefinition Height="Auto"/>
<!--9-->
<RowDefinition Height=".25"/>
<!--10-->
<RowDefinition Height="Auto"/>
<!--11-->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="4"/>
</Grid.ColumnDefinitions>
<Label Text="Services added" FontAttributes="Bold" TextColor="#F65506" Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="2" VerticalTextAlignment="End" HorizontalTextAlignment="Start" FontSize="18"/>
<Label Grid.Column="1" Grid.Row="7" BackgroundColor="#707070" Grid.ColumnSpan="3"/>
<!--This is a line-->
<BoxView BackgroundColor="#F0F0F0" Grid.Row="9" Grid.Column="1" Grid.ColumnSpan="3" CornerRadius="22"/>
<Label Grid.Column="1" Grid.Row="9" Padding="10" TextColor="Black" FontSize="18" Text="{Binding BusinessName}" VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand" Grid.ColumnSpan="2"/>
<Label Grid.Column="3" Grid.Row="9" Padding="0,0,20,0" TextColor="#F65506" FontAttributes="Bold" FontSize="18" Text="View" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand" Grid.ColumnSpan="2"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<CollectionView ItemsSource="{Binding ViewQuoteStatus}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="4"/>
<!--0-->
<RowDefinition Height="30"/>
<!--1-->
<RowDefinition Height="20"/>
<!--2-->
<RowDefinition Height=".25"/>
<!--3-->
<RowDefinition Height="4"/>
<!--4-->
<RowDefinition Height="Auto"/>
<!--5-->
<RowDefinition Height="Auto"/>
<!--6-->
<RowDefinition Height=".25"/>
<!--7-->
<RowDefinition Height="Auto"/>
<!--8-->
<RowDefinition Height="Auto"/>
<!--9-->
<RowDefinition Height=".25"/>
<!--10-->
<RowDefinition Height="Auto"/>
<!--11-->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="4"/>
</Grid.ColumnDefinitions>
<Label Text="Past Orderrs" FontAttributes="Bold" TextColor="#F65506" Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="2" VerticalTextAlignment="End" HorizontalTextAlignment="Start" FontSize="18"/>
<Label Grid.Column="1" Grid.Row="7" BackgroundColor="#707070" Grid.ColumnSpan="3"/>
<!--This is a line-->
<BoxView BackgroundColor="#F0F0F0" Grid.Row="9" Grid.Column="1" Grid.ColumnSpan="3" CornerRadius="22"/>
<Label Grid.Column="1" Grid.Row="9" Padding="10" TextColor="Black" FontSize="18" Text="{Binding BusinessName}" VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand" Grid.ColumnSpan="2"/>
<Label Grid.Column="3" Grid.Row="9" Padding="0,0,20,0" TextColor="#F65506" FontAttributes="Bold" FontSize="18" Text="View" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand" Grid.ColumnSpan="2"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ScrollView>
</ContentPage>
AddedServicesViewModel.cs :
using Shared.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
namespace Shared.ViewModel
{
class AddedServicesViewModel
{
readonly IList<AddedServiceStatus> source;
public ObservableCollection<AddedServiceStatus> ViewAddedServices { get; private set; }
public AddedServicesViewModel()
{
source = new List<AddedServiceStatus>();
CreateAddedServicesCollection();
}
void CreateAddedServicesCollection()
{
source.Add(new AddedServiceStatus
{
BusinessName = "Duck's Duct Cleaning"
});
source.Add(new AddedServiceStatus
{
BusinessName = "Rodney's Home Repair"
});
ViewAddedServices = new ObservableCollection<AddedServiceStatus>(source);
}
}
}
PastOrderViewModel :
using Shared.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
namespace Shared.ViewModel
{
class PastOrderViewModel
{
readonly IList<PastOrderStatus> source;
public ObservableCollection<PastOrderStatus> ViewPastOrders { get; private set; }
public PastOrderViewModel()
{
source = new List<PastOrderStatus>();
CreatePastOrderCollection();
}
void CreatePastOrderCollection()
{
source.Add(new PastOrderStatus
{
BusinessName = "Karen's Magnificent Dog Grooming"
});
source.Add(new PastOrderStatus
{
BusinessName = "Harry's In Home Haircuts"
});
source.Add(new PastOrderStatus
{
BusinessName = "Shelly's Floral Arrangements"
});
ViewPastOrders = new ObservableCollection<PastOrderStatus>(source);
}
}
}
You could also bind a ViewModel to each CollectionView separately.
like:
<CollectionView ItemsSource="{Binding ViewAddedServices}">
<CollectionView.BindingContext>
<viewmodels:AddedServicesViewModel/>
</CollectionView.BindingContext>
...
</CollectionView>
<CollectionView ItemsSource="{Binding ViewPastOrders}">
<CollectionView.BindingContext>
<viewmodels:PastOrderViewModel/>
</CollectionView.BindingContext>
...
</CollectionView>
You can't have two ViewModels binding to a SingleView. (as far a I know)
I see that the DataTemplate in both Collections are the same..... there are many ways to refactor....
You could create two CustomView one with the AddedServicesViewModel and the other with PastOrderViewModel
You can merge the two ViewModels into one, and create a CustomView that it's the collection.
Another thing that I see that It could not work is that you can't have a more than one View Nested in a ScrollView
<ScrollView>
<StackLayout> /* Or any other Layout, Grid, Absolute, Flex etc... */
</StackLayout>
</ScrollView>
Another thing is that a CollectionView with orientation vertical in a ScrollView maybe it won't behave as you expect, since the CollectionView with orientation vertical it has Scroll
Two CollectionViews with orientation vertical in the same View it should have a Height, I would do something like this
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<CollectionView Grid.Row="0" ItemsSource="{Binding ViewQuoteStatus}"> ... </CollectionView>
<CollectionView Grid.Row="1" ItemsSource="{Binding ViewAddedServices}"> ... </CollectionView>
</Grid>
or if you create a custom view (custom control)
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<MyCustomCollectionView Grid.Row="0" ItemsSource="{Binding ViewQuoteStatus}"> ... </MyCustomCollectionView>
<MyCustomCollectionView Grid.Row="1" ItemsSource="{Binding ViewAddedServices}"> ... </MyCustomCollectionView>
</Grid>

Can't use windowManager.ShowWindow() with Caliburn.Micro

I'm currently developing a plugin for Revit (BIM software) and I'm, trying to use WPF and Caliburn.Micro to show a window/dialog when I press a button of the plugin.
So like in the documentation, I have a bootstrapper:
public class Bootstrapper : BootstrapperBase
{
public Bootstrapper()
{
Initialize();
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor<LocationPopupViewModel>();
}
}
}
A simple testing ViewModel:
namespace ExternalForms.ViewModels
{
public class LocationPopupViewModel : Screen
{
private int _horizontalLength;
private int _verticalLength;
public int HorizontalLength
{
get
{
return _horizontalLength;
}
set
{
_horizontalLength = value;
NotifyOfPropertyChange(() => HorizontalLength);
}
}
public int VerticalLength
{
get
{
return _verticalLength;
}
set
{
_verticalLength = value;
NotifyOfPropertyChange(() => VerticalLength);
}
}
}
}
And of course the window that I want to show:
<Window x:Class="ExternalForms.Views.LocationPopupView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ExternalForms.Views"
mc:Ignorable="d" WindowStartupLocation="CenterScreen"
ResizeMode="CanResizeWithGrip"
Title="gebied" Height="300" Width="410"
FontSize="16">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<!--Row 1-->
<TextBlock Text="Stel xxx in" FontWeight="DemiBold" Grid.Column="1" Grid.Row="1" FontSize="18"/>
<!--Row 2-->
<StackPanel Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Width="360" Margin="0, 0, 0, 20">
<TextBlock TextWrapping="Wrap">
Let op dat het gebied een maximale horizontale en verticale lengte mag hebben van 1 kilometer.
</TextBlock>
</StackPanel>
<!--Row 3-->
<TextBlock Text="Horizontaal" Grid.Column="1" Grid.Row="3"/>
<!--Row 4-->
<TextBox x:Name="HorizontalLength" Grid.Row="4" Grid.Column="1" MinWidth="100"/>
<!--Row 5-->
<TextBlock Text="Verticaal" Grid.Column="1" Grid.Row="5"/>
<!--Row 6-->
<TextBox x:Name="VerticalLength" Grid.Row="6" Grid.Column="1" MinWidth="100"/>
<!--Row 7-->
<StackPanel Orientation="Horizontal" Grid.Row="7" Grid.Column="1" Margin="0, 20, 0, 0" Grid.ColumnSpan="2" HorizontalAlignment="Right">
<Button x:Name="SubmitDimensions" IsDefault="True" Width="100" Height="30">OK</Button>
<Button IsCancel="True" IsDefault="True" Width="100" Height="30">Cancel</Button>
</StackPanel>
</Grid>
The function that is trying to show the window:
private void SetBoundingBox()
{
IWindowManager windowManager = new WindowManager();
LocationPopupView locationPopup = new LocationPopupView();
windowManager.ShowWindow(locationPopup, null, null);
}
But when I try to open the dialog in Revit, a window with an error pops up:
UPDATE:
My current project structure looks like this:
Assembly "UI" takes care of all the internal UI elements in Revit (so the buttons in Revit, even though there is currently only one).
The current button in Revit calls the "Get3DBAG" assembly, who does some tasks and eventually calls the "Location" assembly, which calls the Windowmanager.showwindow() method for the WPF views, which are in the "ExternalForms" assembly.
You problem lies in the following line.
LocationPopupView locationPopup = new LocationPopupView();
You are attemping to initialize an instance of View, instead of ViewModel. You should replace this with following.
LocationPopupViewModel locationPopup = new LocationPopupViewModel();
Caliburn Micro would resolve the corresponding View by itself using the naming convention.
Update : Based on Comment
From your comment, it looks like your View/ViewModels are in a different assembly. In that scenario, you need to ensure the assembly is included while Caliburn Micro searches for Views. You can do so by overriding SelectAssemblies method in Bootstrapper.
protected override IEnumerable<Assembly> SelectAssemblies()
{
return new[]
{
Assembly.GetExecutingAssembly()
// Ensure your external assembly is included.
};
}
You would be also interested to read more Custom Conventions using Caliburn Micro

Binding a Command not Working for ListView with Itemsource

I'm trying to add a Clickable ListView-Cell, but I'm probably getting conflicts with the binding.
Each cell should be like a button navigating to a new Page including a given Object.
I already tried with "TapGestureRecognizer".
<ListView x:Name="ListView" HasUnevenRows="True" SelectionMode="Single" >
<ListView.ItemsSource>
<x:Array Type="{x:Type clients:MinRepresentation}">
<clients:MinRepresentation Id="123456789" PlannedStartTime="01-01-2019" PlannedEndTime="01-12-2019" />
<clients:MinRepresentation Id="555555555" PlannedStartTime="12-12-2019" PlannedEndTime="12-12-2019" />
</x:Array>
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="5">
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OrderDetailsCommand}"/>
</Grid.GestureRecognizers>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
[Cell-Template]
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Got the easy solution...
XAML:
<ListView HasUnevenRows="True" SelectionMode="Single" ItemsSource="{Binding VisibleOrders}" ItemSelected="OnListViewItemSelected" ItemTapped="OnListViewItemTapped"/>
ViewModel:
public IList<MinRepresentation> VisibleOrders { get; private set; }
void OnListViewItemSelected(object sender, SelectedItemChangedEventArgs e)
{
MinRepresentation selectedItem = e.SelectedItem as MinRepresentation;
}
void OnListViewItemTapped(object sender, ItemTappedEventArgs e)
{
MinRepresentation tappedItem = e.Item as MinRepresentation;
}

Categories