I have a ListView with a list of comments:
<ListView ItemsSource="{Binding Comments}">
<ListView.ItemTemplate>
<DataTemplate>
<Border Background="{Binding User, Converter={StaticResource UsernameToBackgroundColorConverter}}"
Margin="0,5"
HorizontalAlignment="Stretch"
FlyoutBase.AttachedFlyout="{StaticResource FlyoutBase1}"
Holding="BorderCommento_Holding">
<StackPanel>
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding User}"
FontSize="20"
Grid.Column="0"
FontWeight="Bold"
Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}"/>
<TextBlock HorizontalAlignment="Right"
Text="{Binding DateTime}"
FontSize="20"
Grid.Column="1"
Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}"/>
</Grid>
<TextBlock Margin="5,0,5,5"
Text="{Binding Text}"
FontSize="20"
TextWrapping="Wrap"/>
</StackPanel>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Comment class:
public class Comment
{
public Comment(String id, String user, String text, String date_time)
{
this.Id = id;
this.User = user;
this.Text = text;
this.DateTime = date_time;
}
public string Id { get; private set; }
public string User { get; private set; }
public string Text { get; private set; }
public string DateTime { get; private set; }
}
The Flyout menu that appears when holding on a comment is defined in Page.Resources:
<Page.Resources>
<MenuFlyout x:Name="flyout1" x:Key="FlyoutBase1">
<MenuFlyoutItem x:Name="ReportCommentFlyout"
Text="{Binding User, Converter={StaticResource ReportOrDeleteComment}}"
Click="ReportCommentFlyout_Click"/>
</MenuFlyout>
</Page.Resources>
Now, in the ReportCommentFlyout_Click I need to know the comment Id that is being reported/deleted.
How can I do it?
I've tried
string CommentId = ((Comment)e.OriginalSource).Id;
But the app crashes...
Your app crashes because you cast e.OriginalSource to Comment and it doesn't work because it's not of that type. Usually, it's often safer to way to do this by using "as"
var comment = someObject as Comment;
if (comment != null)
{
....
}
Regarding your problem, have you tried
var menuFlyoutItem = sender as MenuFlyoutItem;
if (menuFlyoutItem != null)
{
var comment = menuFlyoutItem.DataContext as Comment;
if (comment != null)
{
string CommentId = comment.Id;
}
}
Related
I want to add inside my Datagrid-Rowdetails a Listview with my loaded imageURls from my firebase Cloud.
In my method I recieve all data from firebase and convert it into a user object. The Url-array get's appended into a list and converted to the user object.
Here is the method:
async void getAllData() {
Query docref = database.Collection("users");
QuerySnapshot snap = await docref.GetSnapshotAsync();
foreach (DocumentSnapshot docsnap in snap){
Users Employee = docsnap.ConvertTo<Users>();
if (docsnap.Exists) {
List<string> AuthorList = new List<string>();
string UrlLinks = "";
for (int i = 0; i < Employee.ImageUrl.Length; i++) {
string URLS = Employee.ImageUrl[i].ToString();
UrlLinks += URLS + Environment.NewLine;
AuthorList.Add(URLS);
Employee.imagepath = AuthorList;
}
// Every URL links get printed out MessageBox.Show(UrlLinks);
DataGridXAML.Items.Add(Employee);
}
}
}
My User-Class:
namespace First_WPF_Project
{
[FirestoreData]
public class Users
{
[FirestoreProperty]
public string id { get; set; }
[FirestoreProperty]
public int age { get; set; }
[FirestoreProperty]
public string birthday { get; set; }
[FirestoreProperty]
public string name { get; set; }
[FirestoreProperty]
public string[] ImageUrl { get; set; }
public List<string> imagepath { get; set; }
}
}
and my xaml file for the GUI
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DockPanel Background="GhostWhite">
<StackPanel Orientation="Horizontal" >
<ListView Name="listview1" ItemsSource="{Binding imagepath}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding imagepath}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
<Grid Margin="0,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock x:Name="Test123" Text="ID: " FontWeight="Bold" />
<TextBlock Text="{Binding id}" Grid.Column="1" />
<TextBlock Text="Name: " FontWeight="Bold" Grid.Row="1" />
<TextBlock Text="{Binding name}" Grid.Column="1" Grid.Row="1" />
<TextBlock Text="Birthday: " FontWeight="Bold" Grid.Row="2" />
<TextBlock Text="{Binding birthday, StringFormat=d}" Grid.Column="1" Grid.Row="2" />
</Grid>
</DockPanel>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
What do I do wrong or is it not possible in general?
Possible duplications
ListView RowDetailsTemplate
I've tried to create a list and append the list to the user object
If the imagepath property contains valid image URIs, this should work:
<ListView Name="tt" ItemsSource="{Binding imagepath}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
As stated in a comment by #ASh, you should also create one List<string> per Users object in your code:
async void getAllData()
{
Query docref = database.Collection("users");
QuerySnapshot snap = await docref.GetSnapshotAsync();
foreach (DocumentSnapshot docsnap in snap)
{
Users Employee = docsnap.ConvertTo<Users>();
List<string> AuthorList = new List<string>();
Employee.imagepath = AuthorList;
if (docsnap.Exists)
{
string UrlLinks = "";
for (int i = 0; i < Employee.ImageUrl.Length; i++)
{
string URLS = Employee.ImageUrl[i].ToString();
UrlLinks += URLS + Environment.NewLine;
AuthorList.Add(URLS);
}
// Every URL links get printed out MessageBox.Show(UrlLinks);
DataGridXAML.Items.Add(Employee);
}
}
}
I am using below code and MVVM observable, but "Clear" button not clears the content of text boxes.
What I need to do here?
MainWindow.xaml
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30*"/>
<RowDefinition Height="10*"/>
</Grid.RowDefinitions>
<Grid>
<ListView ItemsSource="{Binding Credentials, Mode=OneWay}">
<ListView.View>
<GridView>
<GridViewColumn Header="User Name">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding UserName}" Width="100"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Password">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Password}" Width="100"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
<Grid Grid.Row="1" >
<Button Grid.Column="0" Content="Clear" Command="{Binding ClearTextBoxCommand}" Width="150"/>
</Grid>
</Grid>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MyViewModel();
}
}
MyViewModel.cs
public class MyViewModel : INotifyPropertyChanged
{
private ObservableCollection<Credential> _credentials;
public RelayCommand ClearTextBoxCommand { get; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
var handler = PropertyChanged;
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public ObservableCollection<Credential> Credentials
{
get => _credentials;
set
{
if (value == _credentials)
return;
_credentials = value;
OnPropertyChanged();
}
}
public MyViewModel()
{
var data = new List<Credential> {new Credential {UserName = "user1", Password = "password1"}};
_credentials = new ObservableCollection<Credential>(data);
ClearTextBoxCommand = new RelayCommand(ClearTextBox);
}
private void ClearTextBox()
{
var data = new List<Credential> { new Credential { UserName = "", Password = "" } };
_credentials = new ObservableCollection<Credential>(data);
MessageBox.Show("clear done!");
}
}
public class Credential
{
public string UserName { get; set; }
public string Password { get; set; }
}
Credentials property has notification about change in setter:
public ObservableCollection<Credential> Credentials
{
get => _credentials;
set
{
if (value == _credentials)
return;
_credentials = value;
OnPropertyChanged();
}
}
so if you need to change that collection, use property, not _credentials field
not _credentials = new ObservableCollection<Credential>(data);, but
private void ClearTextBox()
{
var data = new List<Credential> { new Credential { UserName = "", Password = "" } };
Credentials = new ObservableCollection<Credential>(data);
MessageBox.Show("clear done!");
}
Using the Credentials property instead of _credentials field is mandatory. But you do not have to assign a complete new ObservableCollection. Just clear the old one and add a new Credentials object.
private void ClearTextBox()
{
Credentials.Clear();
Credentials.Add(new Credential { UserName = "", Password = "" });
MessageBox.Show("clear done!");
}
This is working at my Application
View:
<UserControl x:Class="PRWSolution.UI.View.MachineView"
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:PRWSolution.UI.View"
xmlns:language="clr-namespace:PRWSolution.UI.Properties.Langs"
xmlns:setting="clr-namespace:PRWSolution.UI.Properties"
mc:Ignorable="d"
DataContext="{Binding Machine, Source={StaticResource Locator}}"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:ie="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:cmd="http://www.galasoft.ch/mvvmlight"
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
Background="{DynamicResource MaterialDesignPaper}"
TextElement.FontWeight="Medium"
TextElement.FontSize="14"
FontFamily="{materialDesign:MaterialDesignFont}">
<Grid>
<StackPanel Orientation="Vertical">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.ColumnSpan="2">
<!--Toolbar for interaction-->
<ToolBarTray Grid.Column="0" Margin="0,5,0,0">
<ToolBar Style="{DynamicResource MaterialDesignToolBar}" ClipToBounds="False">
<Button x:Name="SaveMachine" ToolTip="Save" Command="{Binding SaveCommand, Mode=OneWay}">
<materialDesign:PackIcon Kind="ContentSave" />
</Button>
<Button x:Name="EditeMachine" ToolTip="Edit" Command="{Binding UpdateCommand, Mode=OneWay}">
<materialDesign:PackIcon Kind="Edit" />
</Button>
<Button x:Name="DeleteMachine" ToolTip="Delete" Command="{Binding DeleteCommand, Mode=OneWay}">
<materialDesign:PackIcon Kind="Delete" />
</Button>
<Separator />
<Button x:Name="ClearForm" ToolTip="Clear Form">
<materialDesign:PackIcon Kind="LayersClear" />
</Button>
</ToolBar>
</ToolBarTray>
<ToolBarTray Grid.Column="1" HorizontalAlignment="Right" Margin="0,5,0,0">
<ToolBar Style="{DynamicResource MaterialDesignToolBar}" ClipToBounds="False">
<Button x:Name="ExportMachine" ToolTip="Export" Click="ExportMachine_Click">
<materialDesign:PackIcon Kind="TableExport" />
</Button>
</ToolBar>
</ToolBarTray>
</Grid>
</Grid>
<!--Card for input database information-->
<materialDesign:Card Margin="5">
<StackPanel>
<!--Expander general machine information-->
<Expander Header="{x:Static language:Lang.ExpMachineData }" FontSize="11" HorizontalAlignment="Stretch" Margin="5,5,5,0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<StackPanel Orientation="Vertical">
<TextBox x:Name="txtMachineID" Text="{Binding MachineID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" materialDesign:HintAssist.Hint="{x:Static language:Lang.DgMachineID}" materialDesign:TextFieldAssist.HasClearButton="True" Style="{StaticResource MaterialDesignFloatingHintTextBox}" VerticalAlignment="Center" Margin="5"/>
<TextBox x:Name="txtCustomerID" Text="{Binding CustomerID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" materialDesign:HintAssist.Hint="{x:Static language:Lang.DgCustomerId}" materialDesign:TextFieldAssist.HasClearButton="True" Style="{StaticResource MaterialDesignFloatingHintTextBox}" VerticalAlignment="Center" Margin="5"/>
</StackPanel>
</Grid>
<Grid Grid.Column="1">
<StackPanel Orientation="Vertical">
<ComboBox x:Name="cmbCustomerName" Width="300" HorizontalAlignment="Left" SelectedValuePath="ClientName" SelectedValue="{Binding CustomerName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding MachineCustomer.ClientDataContext, Source={StaticResource Locator}}" DisplayMemberPath="ClientName" materialDesign:HintAssist.Hint="Customer Name" Margin="5"/>
<TextBox x:Name="txtCity" Text="{Binding City, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" materialDesign:HintAssist.Hint="{x:Static language:Lang.DgCity}" materialDesign:TextFieldAssist.HasClearButton="True" Style="{StaticResource MaterialDesignFloatingHintTextBox}" VerticalAlignment="Center" Margin="5"/>
<TextBox x:Name="txtCountry" Text="{Binding Country, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" materialDesign:HintAssist.Hint="{x:Static language:Lang.DgCountry}" materialDesign:TextFieldAssist.HasClearButton="True" Style="{StaticResource MaterialDesignFloatingHintTextBox}" VerticalAlignment="Center" Margin="5"/>
</StackPanel>
</Grid>
</Grid>
</Expander>
<Border Background="{DynamicResource MaterialDesignDivider}" Height="1" HorizontalAlignment="Stretch" SnapsToDevicePixels="True" />
<!--Expander general part info-->
<Expander Header="Part Information" FontSize="11" HorizontalAlignment="Stretch" Margin="5,0,5,0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<StackPanel Orientation="Vertical">
<TextBox x:Name="txtPartName" Text="{Binding PartName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" materialDesign:HintAssist.Hint="Part Name" materialDesign:TextFieldAssist.HasClearButton="True" Style="{StaticResource MaterialDesignFloatingHintTextBox}" VerticalAlignment="Center" Margin="5"/>
<TextBox x:Name="txtPartNumber" Text="{Binding PartNumber, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" materialDesign:HintAssist.Hint="Part Number" materialDesign:TextFieldAssist.HasClearButton="True" Style="{StaticResource MaterialDesignFloatingHintTextBox}" VerticalAlignment="Center" Margin="5"/>
<TextBox x:Name="txtProject" Text="{Binding Project, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" materialDesign:HintAssist.Hint="Project" materialDesign:TextFieldAssist.HasClearButton="True" Style="{StaticResource MaterialDesignFloatingHintTextBox}" VerticalAlignment="Center" Margin="5"/>
</StackPanel>
</Grid>
</Grid>
</Expander>
<Border Background="{DynamicResource MaterialDesignDivider}" Height="1" HorizontalAlignment="Stretch" SnapsToDevicePixels="True" />
<!--Expander for Machine Serials-->
<Expander Header="{x:Static language:Lang.ExpMachineSerials}" FontSize="11" HorizontalAlignment="Stretch" Margin="5,0,5,0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<StackPanel Orientation="Vertical">
<TextBox x:Name="txtSpindleC1" Text="{Binding SpindleC1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" materialDesign:HintAssist.Hint="{x:Static language:Lang.DgSpindleC1}" materialDesign:TextFieldAssist.HasClearButton="True" Style="{StaticResource MaterialDesignFloatingHintTextBox}" VerticalAlignment="Center" Margin="5"/>
<TextBox x:Name="txtSpindleC2" Text="{Binding SpindleC2, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" materialDesign:HintAssist.Hint="{x:Static language:Lang.DgSpindleC2}" materialDesign:TextFieldAssist.HasClearButton="True" Style="{StaticResource MaterialDesignFloatingHintTextBox}" VerticalAlignment="Center" Margin="5"/>
<TextBox x:Name="txtHoningHead" Text="{Binding HoningHead, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" materialDesign:HintAssist.Hint="{x:Static language:Lang.DgHoningHead}" materialDesign:TextFieldAssist.HasClearButton="True" Style="{StaticResource MaterialDesignFloatingHintTextBox}" VerticalAlignment="Center" Margin="5"/>
</StackPanel>
</Grid>
</Grid>
</Expander>
<Border Background="{DynamicResource MaterialDesignDivider}" Height="1" HorizontalAlignment="Stretch" SnapsToDevicePixels="True" />
<!--Expander for Softwareversion-->
<Expander Header="{x:Static language:Lang.ExpSoftwareVersion}" FontSize="11" HorizontalAlignment="Stretch" Margin="5,0,5,5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<StackPanel Orientation="Vertical">
<TextBox x:Name="txtNCVersion" Text="{Binding NCVersion, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" materialDesign:HintAssist.Hint="{x:Static language:Lang.DgNCVersion}" materialDesign:TextFieldAssist.HasClearButton="True" Style="{StaticResource MaterialDesignFloatingHintTextBox}" VerticalAlignment="Center" Margin="5"/>
<TextBox x:Name="txtHMIVersion" Text="{Binding HMIVersion, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" materialDesign:HintAssist.Hint="{x:Static language:Lang.DgHMIVersion}" materialDesign:TextFieldAssist.HasClearButton="True" Style="{StaticResource MaterialDesignFloatingHintTextBox}" VerticalAlignment="Center" Margin="5"/>
<TextBox x:Name="txtHRIVersion" Text="{Binding HRIVersion, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" materialDesign:HintAssist.Hint="{x:Static language:Lang.DgHRIVersion}" materialDesign:TextFieldAssist.HasClearButton="True" Style="{StaticResource MaterialDesignFloatingHintTextBox}" VerticalAlignment="Center" Margin="5"/>
<TextBox x:Name="txtAHSVersion" Text="{Binding AHSVersion, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" materialDesign:HintAssist.Hint="{x:Static language:Lang.DgAHSVersion}" materialDesign:TextFieldAssist.HasClearButton="True" Style="{StaticResource MaterialDesignFloatingHintTextBox}" VerticalAlignment="Center" Margin="5"/>
</StackPanel>
</Grid>
</Grid>
</Expander>
</StackPanel>
</materialDesign:Card>
<!--Database datagrid-->
<DataGrid x:Name="MachineDataGrid" Margin="5" AutoGenerateColumns="False" MaxHeight="700" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" ItemsSource="{Binding DataContext, Mode=TwoWay}" SelectedItem="{Binding Path=MachineSelectedItem, Mode=TwoWay}">
<ie:Interaction.Triggers>
<ie:EventTrigger EventName="SelectionChanged">
<ie:InvokeCommandAction Command="{Binding SelectionChangedCommand}" CommandParameter="{Binding ElementName=MachineDataGrid, Path=SelectedItem}"/>
</ie:EventTrigger>
</ie:Interaction.Triggers>
<DataGrid.Columns>
<materialDesign:DataGridTextColumn Header="{x:Static language:Lang.DgMachineID}" Binding="{Binding MachineID, Mode=TwoWay}"/>
<materialDesign:DataGridTextColumn Header="{x:Static language:Lang.DgCustomerId}" Binding="{Binding CustomerID}"/>
<materialDesign:DataGridTextColumn Header="{x:Static language:Lang.DgCustomerName}" Binding="{Binding CustomerName}"/>
<materialDesign:DataGridTextColumn Header="{x:Static language:Lang.DgCity}" Binding="{Binding City}"/>
<materialDesign:DataGridTextColumn Header="{x:Static language:Lang.DgCountry}" Binding="{Binding Country}"/>
<materialDesign:DataGridTextColumn Header="Part Name" Binding="{Binding PartName}"/>
<materialDesign:DataGridTextColumn Header="Part Number" Binding="{Binding PartNumber}"/>
<materialDesign:DataGridTextColumn Header="Project" Binding="{Binding Project}"/>
<materialDesign:DataGridTextColumn Header="{x:Static language:Lang.DgSpindleC1}" Binding="{Binding SpindleC1}"/>
<materialDesign:DataGridTextColumn Header="{x:Static language:Lang.DgSpindleC2}" Binding="{Binding SpindleC2}"/>
<materialDesign:DataGridTextColumn Header="{x:Static language:Lang.DgHoningHead}" Binding="{Binding HoningHead}"/>
<materialDesign:DataGridTextColumn Header="{x:Static language:Lang.DgNCVersion}" Binding="{Binding NCVersion}"/>
<materialDesign:DataGridTextColumn Header="{x:Static language:Lang.DgHMIVersion}" Binding="{Binding HMIVersion}"/>
<materialDesign:DataGridTextColumn Header="{x:Static language:Lang.DgHRIVersion}" Binding="{Binding HRIVersion}"/>
<materialDesign:DataGridTextColumn Header="{x:Static language:Lang.DgAHSVersion}" Binding="{Binding AHSVersion}"/>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</Grid>
ViewModel:
public class MachineViewModel : ViewModelBase
{
#region public statments Textbox text
//Public statments to get textbox text
public string MachineID { get; set; }
public string CustomerID { get; set; }
public string CustomerName { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string PartName { get; set; }
public string PartNumber { get; set; }
public string Project { get; set; }
public string SpindleC1 { get; set; }
public string SpindleC2 { get; set; }
public string HoningHead { get; set; }
public string NCVersion { get; set; }
public string HMIVersion { get; set; }
public string HRIVersion { get; set; }
public string AHSVersion { get; set; }
#endregion
//DialogService
private IDialogService _dialogService;
//Operation button for save, update, delete, selection changed and print
public ICommand SaveCommand { get; private set; }
public ICommand UpdateCommand { get; private set; }
public ICommand DeleteCommand { get; private set; }
public ICommand ClearCommand { get; private set; }
public ICommand SelectionChangedCommand { get; set; }
//observable collection for machine model
public ObservableCollection<Machine> DataContext { get; set; }
private Machine machineSelectedItem;
public Machine MachineSelectedItem
{
get { return machineSelectedItem; }
set { machineSelectedItem = value; }
}
public object MachineDataGrid { get; set; }
public List<MachineClient> cmbclientDetails;
//PRWContext for general use
private PRWContext context = new PRWContext();
public MachineViewModel()
{
//Commands for save, update, delete and print
SaveCommand = new RelayCommand(() => ExecuteSaveCommand());
UpdateCommand = new RelayCommand(() => ExecuteUpdateCommand());
DeleteCommand = new RelayCommand(() => ExecuteDeleteCommand());
ClearCommand = new RelayCommand(() => ExecuteClearCommand());
SelectionChangedCommand = new RelayCommand(() => ExecuteSelectionChangedCommand());
//Load the data from PRW Database to datagrid
LoadData();
//Normelly done with dependency injection
_dialogService = new DialogService();
}
//execute save
private void ExecuteSaveCommand()
{
Machine machine = new Machine
{
//Machine data
MachineID = MachineID,
CustomerID = CustomerID,
CustomerName = CustomerName,
City = City,
Country = Country,
//Part data
PartName = PartName,
PartNumber = PartNumber,
Project = Project,
//Serial data
SpindleC1 = SpindleC1,
SpindleC2 = SpindleC2,
HoningHead = HoningHead,
//Softwareversion data
NCVersion = NCVersion,
HMIVersion = HMIVersion,
HRIVersion = HRIVersion,
AHSVersion = AHSVersion
};
context.Machines.Add(machine);
context.SaveChanges();
ClearContent();
}
//execute update
private void ExecuteUpdateCommand()
{
Machine machine = context.Machines.FirstOrDefault(w => w.MachineID == MachineID);
machine.CustomerID = CustomerID;
machine.CustomerName = CustomerName;
machine.City = City;
machine.Country = Country;
machine.PartName = PartName;
machine.PartNumber = PartNumber;
machine.Project = Project;
machine.SpindleC1 = SpindleC1;
machine.SpindleC2 = SpindleC2;
machine.HoningHead = HoningHead;
machine.NCVersion = NCVersion;
machine.HMIVersion = HMIVersion;
machine.HRIVersion = HRIVersion;
machine.AHSVersion = AHSVersion;
context.Machines.AddOrUpdate(machine);
context.SaveChanges();
ClearContent();
}
//execute delete
private void ExecuteDeleteCommand()
{
if (machineSelectedItem != null)
{
var dialog = new YesNoDialogViewModel("Question", "Your are Sure to Delete the Record?");
var result = _dialogService.OpenDialog(dialog);
if (result == DialogResults.Yes)
{
Machine machine = context.Machines.FirstOrDefault(w => w.MachineID == MachineID);
context.Machines.Remove(machine);
context.SaveChanges();
ClearContent();
}
}
else
{
var dialog = new AlertDialogViewModel("Attention", "Please select a Record!");
var result = _dialogService.OpenDialog(dialog);
Console.WriteLine(result);
}
}
//execute clear
private void ExecuteClearCommand()
{
ClearContent();
}
// Execute selection changed
private void ExecuteSelectionChangedCommand()
{
if(machineSelectedItem != null)
{
MachineID = machineSelectedItem.MachineID?.ToString() ?? "";
CustomerID = machineSelectedItem.CustomerID?.ToString() ?? "";
CustomerName = machineSelectedItem.CustomerName?.ToString() ?? "";
City = machineSelectedItem.City?.ToString() ?? "";
Country = machineSelectedItem.Country?.ToString() ?? "";
PartName = machineSelectedItem.PartName?.ToString() ?? "";
PartNumber = machineSelectedItem.PartNumber?.ToString() ?? "";
Project = machineSelectedItem.Project?.ToString() ?? "";
SpindleC1 = machineSelectedItem.SpindleC1?.ToString() ?? "";
SpindleC2 = machineSelectedItem.SpindleC2?.ToString() ?? "";
HoningHead = machineSelectedItem.HoningHead?.ToString() ?? "";
NCVersion = machineSelectedItem.NCVersion?.ToString() ?? "";
HMIVersion = machineSelectedItem.HMIVersion?.ToString() ?? "";
HRIVersion = machineSelectedItem.HRIVersion?.ToString() ?? "";
AHSVersion = machineSelectedItem.AHSVersion?.ToString() ?? "";
}
else
{
machineSelectedItem = null;
}
}
//Load data from database to grid
private void LoadData()
{
context.Machines.Load();
this.DataContext = context.Machines.Local;
}
//Clear textboxes
private void ClearContent()
{
MachineID = string.Empty;
CustomerID = string.Empty;
CustomerName = string.Empty;
City = string.Empty;
PartName = string.Empty;
PartNumber = string.Empty;
Project = string.Empty;
Country = string.Empty;
SpindleC1 = string.Empty;
SpindleC2 = string.Empty;
HoningHead = string.Empty;
NCVersion = string.Empty;
HMIVersion = string.Empty;
HRIVersion = string.Empty;
AHSVersion = string.Empty;
}
}
On my Windows Phone App, have a ListBox populated from JSON (webservice).
I need test if a string is equal to some item on ListBox. But I "binding" many informations, and I want test only with {Binding codigo}.
This code not works for me:
private void addProduto(object sender, RoutedEventArgs e)
{
Fields fi = (Fields)this.List1.SelectedItem as Fields;
foreach(var item in List1.Items)
{
Fields fields = item as Fields;
if (fields.codigo == insCodProduto.Text)
{
MessageBox.Show("Esse produto existe!");
}
else
{
MessageBox.Show("Esse produto não existe!");
break;
}
}
My code:
public ObservableCollection<Fields> Items { get; set; }
public class Fields
{
//[JsonProperty(PropertyName = "descricao")]
public string descricao { get; set; }
public double valor_preco_a { get; set; }
public string codigo { get; set; }
public string codigo1 { get; set; }
}
XAML:
<ListBox Name="List1" ItemsSource="{Binding Items}" Margin="0,85,0,0" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="242" />
<ColumnDefinition Width="128" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Margin="0,0,-62,17" Grid.ColumnSpan="3">
<StackPanel.Background>
<SolidColorBrush Color="#FF858585" Opacity="0.5"/>
</StackPanel.Background>
<TextBlock x:Name="NameTxt" Grid.Column="0" Text="{Binding descricao}" TextWrapping="Wrap" FontSize="20" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Grid.Column="1" Text="{Binding valor_preco_a, StringFormat=N2}" TextWrapping="Wrap" Margin="45,20,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
<TextBlock Grid.Column="3" Text="{Binding codigo}" TextWrapping="Wrap" FontSize="35" Margin="370,-50,12,0" Style="{StaticResource PhoneTextNormalStyle}" Foreground="Blue"/>
</StackPanel>
<TextBlock Grid.Column="0" Text="R$" Margin="15,48,158,17" Style="{StaticResource PhoneTextSubtleStyle}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
insCodProduto:
<TextBox InputScope="Number" x:Name="insCodProduto" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Width="161" TextAlignment="Center" Margin="262,152,0,0" Height="78"/>
Cast your item to Fields class first. Now you have access to properties inside
Fields fields = item as Fields;
if (fields.descricao == insCodProduto.Text)
{
//do your stuff
}
You need to cast every List Item to get specific value from it:
foreach(Fields item in List1.Items) //casting listbox item to "Fields"
{
if(item.codigo.ToString() == insCodProduto.Text) //codigo is int type so you'll have to convert it to string
{
MessageBox.Show("ok");
}
}
My ListBox control is working fine, except that the data to be bound is not displaying.
My XAML:
<ListBox x:Name="listFileNames" SelectionMode="Single" Margin="10">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Margin="5" Source="{Binding Path=Image}" Stretch="Fill" Width="50" Height="50"></Image>
<StackPanel Grid.Column="1" Margin="5">
<TextBlock Text="{Binding Path=FileName}" FontWeight="Bold"></TextBlock>
<TextBlock Text="{Binding Path=State}"></TextBlock>
<TextBlock Text="This text shows..."></TextBlock>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
My code:
public struct StyleDocumentFile
{
public string Image;
public string FileName;
public string State;
}
// ......
StyleDocumentFile sdf = new StyleDocumentFile()
{
Image = "/Images/Loading.png",
FileName = "abc",
State = "Extracting Data...",
};
this.listFileNames.Items.Add(sdf);
Change fields to Property. After this, all works fine.
public struct StyleDocumentFile
{
public string Image { get; set; }
public string FileName { get; set; }
public string State { get; set; }
}
You should set ItemsSource in ListBox definition like ItemsSource="{Binding Model.Items}". In addition you must call RaisePropertyChanged in setter of model properties.
So, I am on my way learning MVVM Pattern for Windows Phone, and stuck how to bind the View to my ViewModel. App that I build now is getting current and next 5 days weather and display it to one of my panorama item on MainPage.xaml using UserControl.
I cannot just simply set the Forecasts.ItemsSource = forecast; in my WeatherViewModel, it says that Forecasts (Listbox element name in WeatherView) not exist in the current context.
Can anybody teach me how to bind it? and anybody have a good source/example sample to mvvm pattern in windows-phone? Thanks before.
EDIT:
WeatherModel.cs
namespace JendelaBogor.Models
{
public class WeatherModel
{
public string Date { get; set; }
public string ObservationTime { get; set; }
public string WeatherIconURL { get; set; }
public string Temperature { get; set; }
public string TempMaxC { get; set; }
public string TempMinC { get; set; }
public string Humidity { get; set; }
public string WindSpeedKmph { get; set; }
}
}
WeatherViewModel.cs
namespace JendelaBogor.ViewModels
{
public class WeatherViewModel : ViewModelBase
{
private string weatherURL = "http://free.worldweatheronline.com/feed/weather.ashx?q=";
private const string City = "Bogor,Indonesia";
private const string APIKey = "APIKEY";
private IList<WeatherModel> _forecasts;
public IList<WeatherModel> Forecasts
{
get
{
if (_forecasts == null)
{
_forecasts = new List<WeatherModel>();
}
return _forecasts;
}
private set
{
_forecasts = value;
if (value != _forecasts)
{
_forecasts = value;
this.NotifyPropertyChanged("Forecasts");
}
}
}
public WeatherViewModel()
{
WebClient downloader = new WebClient();
Uri uri = new Uri(weatherURL + City + "&num_of_days=5&extra=localObsTime&format=xml&key=" + APIKey, UriKind.Absolute);
downloader.DownloadStringCompleted += new DownloadStringCompletedEventHandler(ForecastDownloaded);
downloader.DownloadStringAsync(uri);
}
private void ForecastDownloaded(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Result == null || e.Error != null)
{
MessageBox.Show("Cannot load Weather Forecast!");
}
else
{
XDocument document = XDocument.Parse(e.Result);
var current = from query in document.Descendants("current_condition")
select new WeatherModel
{
ObservationTime = DateTime.Parse((string)query.Element("localObsDateTime")).ToString("HH:mm tt"),
Temperature = (string)query.Element("temp_C"),
WeatherIconURL = (string)query.Element("weatherIconUrl"),
Humidity = (string)query.Element("humidity"),
WindSpeedKmph = (string)query.Element("windspeedKmph")
};
this.Forecasts = (from query in document.Descendants("weather")
select new WeatherModel
{
Date = DateTime.Parse((string)query.Element("date")).ToString("dddd"),
TempMaxC = (string)query.Element("tempMaxC"),
TempMinC = (string)query.Element("tempMinC"),
WeatherIconURL = (string)query.Element("weatherIconUrl")
}).ToList();
}
}
}
}
WeatherView.xaml
<UserControl x:Class="JendelaBogor.Views.WeatherView"
xmlns:vm="clr-namespace:JendelaBogor.ViewModels">
<UserControl.DataContext>
<vm:WeatherViewModel />
</UserControl.DataContext>
<Grid Margin="0,-10,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid x:Name="Current" Grid.Row="0" Height="150" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" delay:LowProfileImageLoader.UriSource="{Binding WeatherIconURL}" Width="120" Height="120" VerticalAlignment="Top"/>
<StackPanel Grid.Column="1" Height="200" VerticalAlignment="Top">
<TextBlock Text="{Binding Temperature}" FontSize="22"/>
<TextBlock Text="{Binding ObservationTime}" FontSize="22"/>
<TextBlock Text="{Binding Humidity}" FontSize="22"/>
<TextBlock Text="{Binding Windspeed}" FontSize="22"/>
</StackPanel>
</Grid>
<Grid Grid.Row="1" Height="300" VerticalAlignment="Bottom" Margin="10,0,0,0">
<StackPanel VerticalAlignment="Top">
<StackPanel Height="40" Orientation="Horizontal" Margin="0,0,0,0">
<TextBlock Text="Date" FontSize="22" Width="170"/>
<TextBlock Text="FC" FontSize="22" Width="60"/>
<TextBlock Text="Max" TextAlignment="Right" FontSize="22" Width="90"/>
<TextBlock Text="Min" TextAlignment="Right" FontSize="22" Width="90"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<ListBox ItemsSource="{Binding Forecasts}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Height="40" Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock Text="{Binding Date}" FontSize="22" TextAlignment="Left" Width="170" />
<Image delay:LowProfileImageLoader.UriSource="{Binding WeatherIconURL}" Width="40" Height="40" />
<TextBlock Text="{Binding TempMaxC, StringFormat='\{0\} °C'}" TextAlignment="Right" FontSize="22" Width="90" />
<TextBlock Text="{Binding TempMinC, StringFormat='\{0\} °C'}" TextAlignment="Right" FontSize="22" Width="90" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</StackPanel>
</Grid>
</Grid>
</UserControl>
MainPage.xaml
<controls:PanoramaItem x:Name="Weather" Header="weather">
<views:WeatherView />
</controls:PanoramaItem>
You need to tell the view what viewmodel you are using. By adding
<UserControl
xmlns:vm="clr-namespace:JendelaBogor.ViewModels">
<UserControl.DataContext>
<vm:WeatherViewModel />
</UserControl.DataContext>
</UserControl>
all {Binding}'s are mapped to the class WeatherViewModel. By using the ItemsSource property on the listbox as Reed suggests you can then bind all items from a list that you expose through a property.
If the list is ever changed while running the application, consider using an ObservableCollection and clearing it and adding all new items when new data is received. If you do, your GUI will simply update with it.
The ViewModel doesn't know about the view.
You need to make a Forecasts property on the ViewModel, and bind the ItemsSource to it from your View. In your view, change the ListBox to:
<!-- No need for a name - just add the binding -->
<ListBox ItemsSource="{Binding Forecasts}">
Then, in your ViewModel, add:
// Add a backing field
private IList<WeatherModel> forecasts;
// Add a property implementing INPC
public IList<WeatherModel> Forecasts
{
get { return forecasts; }
private set
{
forecasts = value;
this.RaisePropertyChanged("Forecasts");
}
}
You can then set this in your method:
this.Forecasts = (from query in document.Descendants("weather")
select new WeatherModel
{
Date = DateTime.Parse((string)query.Element("date")).ToString("dddd"),
TempMaxC = (string)query.Element("tempMaxC"),
TempMinC = (string)query.Element("tempMinC"),
WeatherIconURL = (string)query.Element("weatherIconUrl")
})
.ToList(); // Turn this into a List<T>