I'm learning wpf through mvvm.
My application consist of below logic.
Form which has a button that will add a selected components horizontally from Itemcontrol like textbox, combobox and rich textbox and a button whenever the button is clicked.
When the add button is clicked the specified set of components will be added in the line information dynamically.
2) Data will be inserted into the table after pressing the add info button.
3) The issue is after clicking the add info button, the components in the itemscontrol should be readonly. This is the place I'm struggling as of now.
Model.cs:
public class textboxModel
{
public string Text { get; set; }
public string lblText { get; set; }
public string isactive { get; set; }
public bool txtboxreadonly { get; set; }
}
public class ButtonDataModel
{
public string Content { get; set; }
public ICommand Command { get; set; }
public string column { get; set; }
public string isactive { get; set; }
public bool buttreadonly { get; set; }
}
ViewModel.cs:
public class viewmodel : notifyproperties
{
public Relaycommand Status { get; set; }
public Relaycommand AddCommand { get; set; }
public labelconversionOnPauseButtonclick pauseclick = new labelconversionOnPauseButtonclick();
public auditinformation auditid = new auditinformation();
public ButtonDataModel bdm = new ButtonDataModel();
public auditinformation adt
{
get { return auditid; }
set
{
if (value != auditid)
{
auditid = value;
OnPropertyChanged("adt");
}
}
}
public labelconversionOnPauseButtonclick res
{
get { return pauseclick; }
set
{
if (value != pauseclick)
{
pauseclick = value;
OnPropertyChanged("res");
}
}
}
public viewmodel()
{
Status = new Relaycommand(pauseclick.Statusdata);
AddCommand = new Relaycommand(o => auditid.addcommand());
}
}
public class auditinformation : notifyproperties
{
public Relaycommand Command { get; set; }
private string _lines;
public string Lines
{
get { return this._lines; }
set
{
this._lines = value;
this.OnPropertyChanged("Lines");
}
}
private readonly ObservableCollection<ButtonDataModel> _MyDatabutton = new ObservableCollection<ButtonDataModel>();
public ObservableCollection<ButtonDataModel> MyData { get { return _MyDatabutton; } }
private readonly ObservableCollection<textboxModel> _MyDatatxtbox = new ObservableCollection<textboxModel>();
public ObservableCollection<textboxModel> MyDatatxtbox { get { return _MyDatatxtbox; } }
private readonly ObservableCollection<LabelDataModel> _MyDataLabel = new ObservableCollection<LabelDataModel>();
public ObservableCollection<LabelDataModel> MyDataLabel { get { return _MyDataLabel; } }
public void addcommand()
{
int num= 1;
for (int i = 0; i < num; i++)
{
MyDatatxtbox.Add(new textboxModel
{
isactive = "1",
});
MyData.Add(new ButtonDataModel
{
Command = new Relaycommand(o => search()),
Content = "Add info",
isactive = "1",
});
}
}
public void search( )
{
var asss = MyDatatxtbox.Where(a=> a.isactive == "1").Select(a => a.Text);
var itemstoremove = MyDatatxtbox.Where(i => i.isactive == "1").ToList();
foreach (var s in asss)
{
foreach (var a in itemstoremove)
{
if (a.isactive == "1")
{
MessageBox.Show(s);
buttreadonly = true;
}
}
}
// var itemstoremove = MyDatatxtbox.Where(i => i.isactive == "1").ToList();
foreach(var a in itemstoremove)
{
a.isactive = "0";
}
//foreach (var a in itemstoremove)
//{
// a.txtboxreadonly = true;
//}
// var itemstoremovebutton = MyData.Where(i => i.isactive == "1").ToList();
// foreach (var a in itemstoremovebutton)
// {
//// MyData.Remove(a);
// a.isactive = "0";
// }
}
}
window.xaml:
<GroupBox Header="Audit Information" Grid.Row="1">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="0" Text="Member ID"></TextBlock>
<TextBox HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="1" Width="85" ></TextBox>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="2" Text="Claim Number"></TextBlock>
<TextBox HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="3" Width="85" ></TextBox>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="4" Text="Date Audited"></TextBlock>
<TextBox HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="5" Width="85" ></TextBox>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="6" Text="Query ID"></TextBlock>
<TextBox HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="7" Width="85" ></TextBox>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="8" Text="Audit ID"></TextBlock>
<TextBox HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="9" Width="85" ></TextBox>
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Width="85" Height="25" Command="{Binding AddCommand}" Content="Add" Grid.Column="10"></Button>
</Grid>
</GroupBox>
<GroupBox Grid.Row="2" Margin="0,0,0,0" Header="Line Information" >
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="3.2*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="1.8*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Height="22" Grid.Column="0">
<Label HorizontalAlignment="Center" Content="DOS" />
</StackPanel>
<ItemsControl Grid.Column="0" Grid.Row="1" ItemsSource="{Binding adt.MyDatatxtbox}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,50">
<TextBox IsReadOnly="{Binding txtboxreadonly}" Text="{Binding Text, Mode=TwoWay}" Height="25" Width="85" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel Height="22" Grid.Column="1">
<Label HorizontalAlignment="Center" Content="CPT" />
</StackPanel>
<ItemsControl Grid.Column="1" Grid.Row="1" ItemsSource="{Binding adt.MyDatatxtbox}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,50">
<TextBox IsReadOnly="{Binding txtboxreadonly}" Margin="0,0,30,0" Text="{Binding Text, Mode=TwoWay}" Height="25" Width="85" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel Height="22" Grid.Column="2">
<Label HorizontalAlignment="Right" Content="Open-close Modifier" Margin="0,0,-17,0" Width="121" />
</StackPanel>
<ItemsControl Grid.Column="2" Grid.Row="1" ItemsSource="{Binding adt.MyDatatxtbox}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,50">
<TextBox IsReadOnly="{Binding txtboxreadonly}" Margin="0,0,30,0" Text="{Binding Text, Mode=TwoWay}" Height="25" Width="85" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel Height="22" Grid.Column="3">
<Label HorizontalAlignment="Center" Content="Comments" />
</StackPanel>
<ItemsControl Grid.Column="3" Grid.Row="1" ItemsSource="{Binding adt.MyDatatxtbox}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,10">
<RichTextBox IsReadOnly="{Binding txtboxreadonly}" Margin="0,0,0,0" Height="65" Width="425" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel Height="22" Grid.Column="4">
<Label HorizontalAlignment="Center" Content="Line Status" />
</StackPanel>
<ItemsControl Grid.Column="4" Grid.Row="1" ItemsSource="{Binding adt.MyDatatxtbox}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10,0,0,50">
<ComboBox IsEnabled= "{Binding txtboxreadonly}" Margin="0,0,0,0" Height="25" Width="95" >
<ComboBoxItem Content="Coffie"></ComboBoxItem>
<ComboBoxItem Content="Tea"></ComboBoxItem>
</ComboBox>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel Height="22" Grid.Column="5">
<Label HorizontalAlignment="Center" Content="Additional Comments" />
</StackPanel>
<ItemsControl Grid.Column="5" Grid.Row="1" ItemsSource="{Binding adt.MyDatatxtbox}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,10">
<RichTextBox IsReadOnly="{Binding txtboxreadonly}" Margin="0,0,0,0" Height="65" Width="425" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl Grid.Column="6" Grid.Row="1" ItemsSource="{Binding adt.MyData}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,50">
<Button Margin="0,0,0,0" Height="25" Width="55" Content="{Binding Content}" Command="{Binding Command}" >
</Button>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</ScrollViewer>
</GroupBox>
</Grid>
</Grid>
</TabItem>
</TabControl>
So the question is how to disable/readonly the Line Information ,textbox and cpt on add info button click.
Dirty way would be adding a "global" bool property in your ViewModel and binding it to your Controls IsEnabled/ReadOnly Properties.
Related
I have a nested listview. When clicks on it's button I want to get it's row index. Now I got the index as -1 always.
<ListView x:Name="Mainlist" HorizontalAlignment="Stretch">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:CurrentBooksList">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" ></ColumnDefinition>
</Grid.ColumnDefinitions>
<ListView x:Name="sublist1" ItemsSource="{x:Bind CurrentFoldersArray}" Grid.Column="0" BorderBrush="Black" BorderThickness="0,0,0,1" HorizontalAlignment="Stretch" >
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:CurrentFoldersList">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Foreground="Black" FontWeight="Bold" Grid.Column="0" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Text="{x:Bind BookCode}"/>
<ListView x:Name="sublist2" ItemsSource="{x:Bind CurrentBookArray1}" Grid.Column="1" HorizontalAlignment="Stretch" >
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:CurrentBusList1">
<Button Width="120" Height="40" Text="{x:Bind Lockbook}" Click="LockMyBook_btn_Click">
</Button>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
private void LockMyBook_btn_Click(object sender, RoutedEventArgs e)
{
int selectedIndx = Mainlist.SelectedIndex; //always return -1
}
How can I get the row number of mainlist view, when user clicks on it's inner listview's button?
Yes it runs well. By getting row number of mainlist, I want to access corresponding items in CurrentBooksList
Well, it's strange. If you're using a basic UWP button control, it doesn't have Text property, your code should not work. But I didn't care about this point, your question was not related to it.
In your button's click event handler, you could get its DataContext, then you could convert it to an CurrentBusList1 object. By this CurrentBusList1 object, you could do some judgements from your 'Mainlist' ItemsSource and get the selected CurrentBooksList object.
public sealed partial class MainPage : Page
{
public ObservableCollection<CurrentBooksList> currentBooksLists { get; set; }
public MainPage()
{
this.InitializeComponent();
currentBooksLists = new ObservableCollection<CurrentBooksList>();
ObservableCollection<CurrentFoldersList> currentFoldersLists = new ObservableCollection<CurrentFoldersList>();
currentFoldersLists.Add(new CurrentFoldersList() { BookCode = "abc123", CurrentBookArray1 = new ObservableCollection<CurrentBusList1>() { new CurrentBusList1() { Lockbook = "123abc" }, new CurrentBusList1() { Lockbook = "123def" } } });
currentFoldersLists.Add(new CurrentFoldersList() { BookCode = "def456", CurrentBookArray1 = new ObservableCollection<CurrentBusList1>() { new CurrentBusList1() { Lockbook = "def456" } } });
currentBooksLists.Add(new CurrentBooksList() { CurrentFoldersArray = currentFoldersLists });
}
private void Button_Click(object sender, RoutedEventArgs e)
{
int index;
var subSelectedItem = ((FrameworkElement)sender).DataContext as CurrentBusList1;
foreach (var item in currentBooksLists)
{
foreach (var folder in item.CurrentFoldersArray)
{
foreach (var bus in folder.CurrentBookArray1)
{
if (bus == subSelectedItem)
{
index = currentBooksLists.IndexOf(item);
break;
}
}
}
}
}
}
public class CurrentBooksList
{
public ObservableCollection<CurrentFoldersList> CurrentFoldersArray { get; set; }
}
public class CurrentFoldersList
{
public string BookCode { get; set; }
public ObservableCollection<CurrentBusList1> CurrentBookArray1 { get; set; }
}
public class CurrentBusList1
{
public string Lockbook { get; set; }
}
<ListView x:Name="Mainlist" HorizontalAlignment="Stretch" ItemsSource="{x:Bind currentBooksLists}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:CurrentBooksList">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" ></ColumnDefinition>
</Grid.ColumnDefinitions>
<ListView x:Name="sublist1" ItemsSource="{x:Bind CurrentFoldersArray}" Grid.Column="0" BorderBrush="Black" BorderThickness="0,0,0,1" HorizontalAlignment="Stretch" >
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:CurrentFoldersList">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Foreground="Black" FontWeight="Bold" Grid.Column="0" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Text="{x:Bind BookCode}"/>
<ListView x:Name="sublist2" ItemsSource="{x:Bind CurrentBookArray1}" Grid.Column="1" HorizontalAlignment="Stretch" >
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:CurrentBusList1">
<Button Width="120" Height="40" Content="{x:Bind Lockbook}" Click="Button_Click">
</Button>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I'm writing my first program with the use wpf and mvvm.
Have a problem, that in the case of changes data in fields of selecteditem, selecting a new item becomes impossible.
If add to listview attribute SelectionMode="Single", then if many times try pick item, exeption:
The element with the same key has already been added.
image: https://www.dropbox.com/s/ey7izl19803uuhc/1.png
If this attribute is removed, then pick another item, simply does not occur.
Image: https://dl.dropboxusercontent.com/u/32438899/2.png
If the data has not changed, the navigation works fine.
XAML code:
<?xml version="1.0" encoding="utf-8" ?>
<Window x:Class="MHConfigurator.Views.MainView"
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"
mc:Ignorable="d"
d:DataContext="{Binding Path=MainViewModel}"
Title="Редактирование шаблонов писем" Height="Auto" Width="1000" MinWidth="1000" MinHeight="400">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0" Margin="7">
<TextBlock DockPanel.Dock="Left" Margin="5,5,2,5" HorizontalAlignment="Left">Поиск:</TextBlock>
<TextBox DockPanel.Dock="Right" Margin="2,2,2,2" HorizontalAlignment="Stretch" Text="{Binding SearchString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox>
</DockPanel>
<ListView Grid.Row="1" ItemsSource="{Binding Path=MailProperties, Mode=TwoWay}" Width="Auto" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" Margin="5" SelectedItem="{Binding Path=CurrentProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding ButtonID, Mode=TwoWay}" Header="ID шаблона" Width="Auto" />
<GridViewColumn DisplayMemberBinding="{Binding Description, Mode=TwoWay}" Header="Описание" Width="Auto" />
</GridView>
</ListView.View>
</ListView>
<Grid VerticalAlignment="Center" Grid.Row="2" DataContext="{Binding CurrentProperty}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0" Grid.Column="0">
<TextBlock DockPanel.Dock="Left" Margin="5,5,2,5" VerticalAlignment="Center" HorizontalAlignment="Left">ID шаблона:</TextBlock>
<TextBox DockPanel.Dock="Right" Margin="2,2,2,2" VerticalAlignment="Center" HorizontalAlignment="Stretch"
VerticalContentAlignment="Center" Text="{Binding ButtonID}"></TextBox>
</DockPanel>
<DockPanel Grid.Row="1" Grid.Column="0">
<CheckBox DockPanel.Dock="Left" HorizontalAlignment="Left" Margin="5" VerticalAlignment="Center" IsChecked="{Binding FillSubject}">Заполнять тему</CheckBox>
</DockPanel>
<DockPanel Grid.Row="2" Grid.Column="0">
<CheckBox DockPanel.Dock="Left" HorizontalAlignment="Left" Margin="5" VerticalAlignment="Center" IsChecked="{Binding FillTO}">Заполнять адресатов</CheckBox>
</DockPanel>
<DockPanel Grid.Row="3" Grid.Column="0">
<CheckBox DockPanel.Dock="Left" HorizontalAlignment="Left" Margin="5" VerticalAlignment="Center" IsChecked="{Binding FillCopy}">Заполнять копию</CheckBox>
</DockPanel>
<DockPanel Grid.Row="4" Grid.Column="0">
<CheckBox DockPanel.Dock="Left" HorizontalAlignment="Left" Margin="5" VerticalAlignment="Center" IsChecked="{Binding FillHideCopy}">Заполнять скрытую копию</CheckBox>
</DockPanel>
<DockPanel Grid.Row="5" Grid.Column="0">
<CheckBox DockPanel.Dock="Left" HorizontalAlignment="Left" Margin="5" VerticalAlignment="Center" IsChecked="{Binding HighImportance}">Высокая важность</CheckBox>
</DockPanel>
<DockPanel Grid.Row="0" Grid.Column="1">
<TextBlock DockPanel.Dock="Left" VerticalAlignment="Center" Margin="10,5,2,5" Width="115" >Описание шаблона:</TextBlock>
<TextBox DockPanel.Dock="Left" Margin="2,2,5,2" TextWrapping="Wrap" VerticalContentAlignment="Center" Text="{Binding Description}"></TextBox>
</DockPanel>
<DockPanel Grid.Row="1" Grid.Column="1">
<TextBlock DockPanel.Dock="Left" VerticalAlignment="Center" Margin="10,5,2,5" Width="115">Тема письма:</TextBlock>
<TextBox DockPanel.Dock="Left" Margin="2,2,5,2" TextWrapping="Wrap" VerticalContentAlignment="Center" Text="{Binding Subject}"></TextBox>
</DockPanel>
<DockPanel Grid.Row="2" Grid.Column="1">
<TextBlock DockPanel.Dock="Left" VerticalAlignment="Center" Margin="10,5,2,5" Width="115">Адресаты:</TextBlock>
<TextBox DockPanel.Dock="Left" Margin="2,2,5,2" TextWrapping="Wrap" VerticalContentAlignment="Center" Text="{Binding TO}"></TextBox>
</DockPanel>
<DockPanel Grid.Row="3" Grid.Column="1">
<TextBlock DockPanel.Dock="Left" VerticalAlignment="Center" Margin="10,5,2,5" Width="115">Копия:</TextBlock>
<TextBox DockPanel.Dock="Left" Margin="2,2,5,2" TextWrapping="Wrap" VerticalContentAlignment="Center" Text="{Binding Copy}"></TextBox>
</DockPanel>
<DockPanel Grid.Row="4" Grid.Column="1">
<TextBlock DockPanel.Dock="Left" VerticalAlignment="Center" Margin="10,5,2,5" Width="115">Скрытая копия:</TextBlock>
<TextBox DockPanel.Dock="Left" Margin="2,2,5,2" TextWrapping="Wrap" VerticalContentAlignment="Center" Text="{Binding HideCopy}"></TextBox>
</DockPanel>
<DockPanel Grid.Row="5" Grid.Column="1">
<CheckBox DockPanel.Dock="Left" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="5">Напоминание</CheckBox>
<TextBlock DockPanel.Dock="Left" VerticalAlignment="Center" Margin="4">Время напоминания:</TextBlock>
<TextBox DockPanel.Dock="Left" Margin="2,2,5,2" VerticalContentAlignment="Center"></TextBox>
</DockPanel>
<DockPanel Grid.Row="6" Grid.Column="1">
<CheckBox DockPanel.Dock="Left" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="5">Заполнять текст письма</CheckBox>
</DockPanel>
<DockPanel Grid.Row="7" Grid.Column="0" Grid.ColumnSpan="2">
<Button DockPanel.Dock="Left" Margin="15" HorizontalAlignment="Left" VerticalAlignment="Center" Width="150" Height="40">Добавить новый шаблон</Button>
<Button DockPanel.Dock="Left" Margin="15" HorizontalAlignment="Left" VerticalAlignment="Center" Width="150" Height="40">Сохранить</Button>
<Button DockPanel.Dock="Left" Margin="15" HorizontalAlignment="Left" VerticalAlignment="Center" Width="150" Height="40">Отмена</Button>
<TextBlock DockPanel.Dock="Left" Margin="0,4,4,4" VerticalAlignment="Center">Заметка:</TextBlock>
<TextBox DockPanel.Dock="Right" Margin="5" TextWrapping="Wrap" AcceptsReturn="True" Height="70" HorizontalAlignment="Stretch" VerticalScrollBarVisibility="Visible"
SpellCheck.IsEnabled="True" Language="ru-ru"></TextBox>
</DockPanel>
</Grid>
</Grid>
</Window>
In viewmodel problems can not be. It is very easy, PropertyChanged called whenever necessary.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MugenMvvmToolkit;
using MugenMvvmToolkit.ViewModels;
using MugenMvvmToolkit.Models;
using System.Windows.Input;
using MHConfigurator.Models;
using System.Windows;
namespace MHConfigurator.ViewModels
{
class MainViewModel : ViewModelBase
{
public MainViewModel()
{
_mailProperties = new ObservableCollection<MailProperty>(DAL.GetDAL().MailPropertys);
//MailsTemplates = DAL.GetDAL().GetEmptyMailTemplates();
}
#region Fields
#region Backing Fields
private ObservableCollection<MailProperty> _mailProperties;
private MailProperty _currentProperty;
private string _searchString;
private MailProperty _originalCurrentProperty;
private bool _currentPropertyChanged = false;
private List<MailsTemplate> _mailsTemplates;
private int _selectedMailTemplate;
#endregion
public string SearchString
{
get
{
if (_searchString.IsNullOrEmpty()) return "";
return _searchString;
}
set
{
bool stringContains = _searchString != null && value.Contains(_searchString);
_searchString = value;
CurrentProperty = null;
//Not matter
}
}
public ObservableCollection<MailProperty> MailProperties
{
get { return _mailProperties; }
set
{
_mailProperties = value;
//OnPropertyChanged(new PropertyChangedEventArgs("MailProperties"));
OnPropertyChanged();
}
}
public MailProperty CurrentProperty
{
get { return _currentProperty; }
set
{/*
if ((_originalCurrentProperty != null)&&(_currentPropertyChanged)&&(_originalCurrentProperty!=_currentProperty)) //Если выбран другой объект и есть несохранённые изменения
{
MessageBoxResult result = MessageBox.Show("Есть несохранённые изменения. Сохранить?", "Несохранённые изменения", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result == MessageBoxResult.Yes)
{
}
else
{
MailProperties[MailProperties.IndexOf(_currentProperty)] = _originalCurrentProperty; //Находим в коллекции изменённый объект и заменить его оригиналом
}
}
_originalCurrentProperty = Helper.DeepClone(_currentProperty); //Делаем резервную копию
SelectedMailTemplate = value.BodyID; //выставляем id шаблона
*/
_currentProperty = value;
// OnPropertyChanged(new PropertyChangedEventArgs("CurrentProperty"));
OnPropertyChanged();
}
}
public List<MailsTemplate> MailsTemplates
{
get { return _mailsTemplates; }
set
{
_mailsTemplates = value;
OnPropertyChanged();
}
}
public int SelectedMailTemplate
{
get { return _selectedMailTemplate; }
set
{
_selectedMailTemplate = value;
CurrentProperty.BodyID = value;
OnPropertyChanged();
}
}
#endregion
#region Commands
public ICommand NewCommand { get; private set; }
public ICommand SaveCommand { get; private set; }
public ICommand CancelCommand { get; private set; }
#region Execute
#endregion
#region CanExecute
#endregion
#endregion
}}
I have no idea.
I will be glad to any ideas.
P.S.: Sorry for my bad english.
This is my class:
public class ZuResults
{
public Direct_Matches[] direct_matches { get; set; }
public int found { get; set; }
public string query { get; set; }
public ZuResults()
{
}
}
public class Direct_Matches
{
public object[] data { get; set; }
public string[] headwords { get; set; }
public Metadata metadata { get; set; }
}
public class Metadata
{
public string pos { get; set; }
public string lang { get; set; }
}
This is the ListView to which I am trying to bind this class:
<ListView Grid.Row="0" Margin="0,50,0,0" x:Name="listZuResults"
SelectionMode="Single" Background="White"
ScrollViewer.VerticalScrollBarVisibility="Auto" ItemsSource="{Binding}"
BorderThickness="0,0,1,0" BorderBrush="DarkGray">
<ListView.ItemTemplate>
<DataTemplate>
<Grid BorderThickness="1,1,1,2" BorderBrush="LightGray" Width="350">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel VerticalAlignment="Center">
<TextBlock Margin="0,0,0,0" Grid.Row="0" x:Name="Query" Foreground="{Binding FontColor}" TextWrapping="Wrap" Text="Query" FontSize="15" FontWeight="Bold"/>
<TextBlock Margin="0,0,0,0" Grid.Row="0" x:Name="txtQuery" Foreground="{Binding FontColor}" TextWrapping="Wrap" Text="{Binding query, Mode=TwoWay}" FontSize="12"/>
<TextBlock Margin="0,0,0,0" Grid.Row="0" x:Name="Found" Foreground="{Binding FontColor}" TextWrapping="Wrap" Text="Results found" FontSize="15" FontWeight="Bold"/>
<TextBlock Margin="0,0,0,0" Grid.Row="0" x:Name="txtFound" Foreground="{Binding FontColor}" TextWrapping="Wrap" Text="{Binding found, Mode=TwoWay}" FontSize="12"/>
<ListView ItemsSource="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=direct_matches[1]}">
<DataTemplate>
<Grid BorderThickness="1,1,1,2" BorderBrush="LightGray" Width="350">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel VerticalAlignment="Center">
<TextBlock Margin="0,0,0,0" Grid.Row="0" x:Name="Metadata" Foreground="{Binding FontColor}" TextWrapping="Wrap" Text="Metadata" FontSize="15" FontWeight="Bold"/>
<ListView ItemsSource="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=metadata}">
<TextBlock Margin="0,0,0,0" Grid.Row="0" x:Name="Pos" Foreground="{Binding FontColor}" TextWrapping="Wrap" Text="Pos" FontSize="15" FontWeight="Bold"/>
<TextBlock Margin="0,0,0,0" Grid.Row="0" x:Name="txtPos" Foreground="{Binding FontColor}" TextWrapping="Wrap" Text="{Binding pos}" FontSize="12"/>
</ListView>
</StackPanel>
</Grid>
</DataTemplate>
</ListView>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
When I set the ItemsSource of listZuResults in my MainPage.xaml code-behind, the only values that actually appear when I debug are those of txtQuery and txtFound. How do I display the rest of the data, for example 'pos' and 'lang'?
I have class
public class Clip
{
public string ID { get; set; }
public string Name { get; set; }
public int? Duration { get; set; }
}
And ObservableCollection
public ObservableCollection<Clip> _clipsFound;
public ObservableCollection<Clip> collection
{
get { return _clipsFound; }
set
{
_clipsFound = value;
OnPropertyChanged();
}
}
OnPropertyChanged() is invoked when I do
_clipsFound = collection
I want binding data from collection to ListBox with three columns: ID, Name, Duration
Initialize
ID = id;
collection = new ObservableCollection<Clip>();
_clipsFound = collection;
_clipsFound.Clear();
ICollection<Clip> ClipF = await Service.GetClips(ID);
ICollection<Clip> Clipcol = ClipF;
collection = new ObservableCollection<Clip>(Clipcol);
I try do this, but it doesn't work
<ListBox Grid.Row="2" ItemsSource="{Binding collection}" BorderBrush="Transparent" >
<ListBox.ItemTemplate>
<DataTemplate DataType="ui:Clip">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="{Binding Title}"
VerticalAlignment="Center"
HorizontalAlignment="Left"
TextTrimming="CharacterEllipsis"
Foreground="#FF4F4F4F"
FontSize="12"
Margin="55 0 0 0"/>
<TextBlock Grid.Column="1"
Margin="0 0 45 0"
Text="{Binding Duration}"
VerticalAlignment="Center"
HorizontalAlignment="Right"
FontSize="11"
Foreground="#FF4F4F4F"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
What did I do wrong?
You cannot send data from viewmodel to view without setting DataContext. DataContext is like channel or bridge between ViewModel and View.
This code sets DataContext:
<Window.DataContext>
<vm:MainWindowViewModel />
</Window.DataContext>
Let's see work example:
Your ViewModel:
public class MainWindowViewModel
{
publicMainWindowViewModel
{
LoadData();
}
private void LoadData()
{
_clipsFound=new ObservableCollection<Clip>();
for(int startIndex=0; startIndex<10; startIndex++)
{
collection.Add(new Clip(){ID=startIndex, Name="Bob", Duration=startIndex++});
}
}
public ObservableCollection<Clip> _clipsFound;
public ObservableCollection<Clip> collection
{
get
{
return _clipsFound;
}
set
{
_clipsFound = value;
}
}
}
Your XAML:
<Window x:Class="DataGridSelectedItemsWpfApplication.MainWindow"
...The code omitted for the brevity...
xmlns:vm="clr-namespace:DataGridSelectedItemsWpfApplication.ViewModel"
Title="MainWindow" WindowStartupLocation="CenterScreen" Height="550" Width="525">
<Window.DataContext>
<vm:MainWindowViewModel />
</Window.DataContext>
<ListBox Grid.Row="2" ItemsSource="{Binding collection}" BorderBrush="Transparent" >
<ListBox.ItemTemplate>
<DataTemplate DataType="ui:Clip">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding ID}" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="11" Margin="2" Foreground="#FF4F4F4F"/>
<TextBlock Grid.Column="1" Margin="2" Text="{Binding Name}" VerticalAlignment="Center" HorizontalAlignment="Center" TextTrimming="CharacterEllipsis" Foreground="#FF4F4F4F" FontSize="12"/>
<TextBlock Grid.Column="2" Margin="2" Text="{Binding Duration}" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="11" Foreground="#FF4F4F4F"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Window>
There are many ways to set DataContext.
Hi I am working on a networking application for which I am using C# WPF and MVVM pattern. This would be a fast configuration application so that user can configure a device from application. The problem of confusion is that I want want to take information about vlans and there could be multiple vlans a user can create. So I need to take multiple information from user at the same time and in the end I will configure all the values via telnet command. What would be the possible and simple way of taking multiple inputs from user and store it till end so that it could be configured correctly?
Suggestions would be greatly appreciable.
My code for VLANS ViewModel is:
public class VLANSViewModel : WizardPageViewModelBase
{
#region Fields
#endregion // end region fields
#region Constructor
public VLANSViewModel(ConfigurationLibrary configuration)
: base(configuration)
{
VlanIP1 = "192";
VlanIP2 = "168";
VlanIP3 = "1";
VlanIP4 = "1";
}
#endregion
#region Properties
public string VlanName
{
get
{
return this.ConfigurationLibrary.ConfigLibraryVlanName;
}
set
{
if (String.Equals(this.ConfigurationLibrary.ConfigLibraryVlanName, value))
{
return;
}
this.ConfigurationLibrary.ConfigLibraryVlanName = value;
this.OnPropertyChanged("VlanName");
}
}
public string VlanID
{
get
{
return this.ConfigurationLibrary.ConfigLibraryVlanName;
}
set
{
if (String.Equals(this.ConfigurationLibrary.ConfigLibraryVlanName, value))
{
return;
}
this.ConfigurationLibrary.ConfigLibraryVlanName = value;
this.OnPropertyChanged("VlanID");
}
}
public string VlanIP1
{
get
{
return this.ConfigurationLibrary.ConfigLibraryVlanIp1;
}
set
{
if (!String.Equals(this.ConfigurationLibrary.ConfigLibraryVlanIp1, value))
{
this.ConfigurationLibrary.ConfigLibraryVlanIp1 = value;
this.OnPropertyChanged("VlanIP1");
}
}
}
public string VlanIP2
{
get
{
return this.ConfigurationLibrary.ConfigLibraryVlanIp2;
}
set
{
if (!String.Equals(this.ConfigurationLibrary.ConfigLibraryVlanIp2, value))
{
this.ConfigurationLibrary.ConfigLibraryVlanIp2 = value;
this.OnPropertyChanged("VlanIP2");
}
}
}
public string VlanIP3
{
get
{
return this.ConfigurationLibrary.ConfigLibraryVlanIp3;
}
set
{
if (!String.Equals(this.ConfigurationLibrary.ConfigLibraryVlanIp3, value))
{
this.ConfigurationLibrary.ConfigLibraryVlanIp3 = value;
this.OnPropertyChanged("VlanIP3");
}
}
}
public string VlanIP4
{
get
{
return this.ConfigurationLibrary.ConfigLibraryVlanIp4;
}
set
{
if (!String.Equals(this.ConfigurationLibrary.ConfigLibraryVlanIp4, value))
{
this.ConfigurationLibrary.ConfigLibraryVlanIp4 = value;
this.OnPropertyChanged("VlanIP4");
}
}
}
public string VlanDefaultRoute1
{
get
{
return this.ConfigurationLibrary.ConfigLibraryVlanDefaultRoute1;
}
set
{
if (!String.Equals(this.ConfigurationLibrary.ConfigLibraryVlanDefaultRoute1, value))
{
this.ConfigurationLibrary.ConfigLibraryVlanDefaultRoute1 = value;
this.OnPropertyChanged("VlanDefaultRoute1");
}
}
}
public string VlanDefaultRoute2
{
get
{
return this.ConfigurationLibrary.ConfigLibraryVlanDefaultRoute2;
}
set
{
if (!String.Equals(this.ConfigurationLibrary.ConfigLibraryVlanDefaultRoute2, value))
{
this.ConfigurationLibrary.ConfigLibraryVlanDefaultRoute2 = value;
this.OnPropertyChanged("VlanDefaultRoute2");
}
}
}
public string VlanDefaultRoute3
{
get
{
return this.ConfigurationLibrary.ConfigLibraryVlanDefaultRoute3;
}
set
{
if (!String.Equals(this.ConfigurationLibrary.ConfigLibraryVlanDefaultRoute3, value))
{
this.ConfigurationLibrary.ConfigLibraryVlanDefaultRoute3= value;
this.OnPropertyChanged("VlanDefaultRoute3");
}
}
}
public string VlanDefaultRoute4
{
get
{
return this.ConfigurationLibrary.ConfigLibraryVlanDefaultRoute4;
}
set
{
if (!String.Equals(this.ConfigurationLibrary.ConfigLibraryVlanDefaultRoute4, value))
{
this.ConfigurationLibrary.ConfigLibraryVlanDefaultRoute4 = value;
this.OnPropertyChanged("VlanDefaultRoute4");
}
}
}
#endregion // end region fields
public override string DisplayName
{
get
{
return Strings.PageDisplayName_VLAN;
}
}
#region Methods
internal override bool IsValid()
{
return true;
}
#endregion
}
And my view for VLANS is :
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label
Grid.Row="0"
Grid.Column="0"
VerticalAlignment="Center"
Content="VLAN NAME"
Foreground="Black"
Opacity="0.8"
/>
<ComboBox
Grid.Row="0"
Grid.Column="1"
Margin="0,5,0,0"
Height="25"
Foreground="Black"
Opacity="0.8"
Width="Auto"
Text="{Binding VlanName, UpdateSourceTrigger=PropertyChanged}"
/>
<Label
Grid.Row="1"
Grid.Column="0"
VerticalAlignment="Center"
Content="VLAN ID"
Foreground="Black"
Opacity="0.8"
/>
<TextBox
Grid.Row="1"
Grid.Column="1"
Margin="0,5,0,0"
Height="25"
Foreground="Black"
Opacity="0.8"
Width="Auto"
Text="{Binding VlanID, UpdateSourceTrigger=PropertyChanged}"
/>
<Label
Grid.Row="2"
Grid.Column="0"
VerticalAlignment="Center"
Content="IP FOR VLAN"
Foreground="Black"
Opacity="0.8"
/>
<Grid
Grid.Column="1"
Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<TextBox
Grid.Row="2"
Grid.Column="0"
Margin="5"
VerticalAlignment="Center"
MaxLength="3"
Width="30"
Foreground="Black"
Opacity="0.8"
Text="{Binding VlanIP1, UpdateSourceTrigger=PropertyChanged}"
/>
<TextBox
Grid.Row="2"
Grid.Column="1"
Margin="5"
VerticalAlignment="Center"
MaxLength="3"
Width="30"
Foreground="Black"
Opacity="0.8"
Text="{Binding VlanIP2, UpdateSourceTrigger=PropertyChanged}"
/>
<TextBox
Grid.Row="2"
Grid.Column="2"
Margin="5"
VerticalAlignment="Center"
MaxLength="3"
Width="30"
Foreground="Black"
Opacity="0.8"
Text="{Binding VlanIP3, UpdateSourceTrigger=PropertyChanged}"
/>
<TextBox
Grid.Row="2"
Grid.Column="3"
Margin="5"
VerticalAlignment="Center"
MaxLength="3"
Width="30"
Foreground="Black"
Opacity="0.8"
Text="{Binding VlanIP4, UpdateSourceTrigger=PropertyChanged}"
/>
</Grid>
<Label
Grid.Row="3"
Grid.Column="0"
VerticalAlignment="Center"
Content="DEFAULT ROUTE"
Foreground="Black"
Opacity="0.8"
/>
<Grid
Grid.Row="3"
Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<TextBox
Grid.Row="2"
Grid.Column="0"
Margin="5"
VerticalAlignment="Center"
MaxLength="3"
Width="30"
Foreground="Black"
Opacity="0.8"
Text="{Binding VlanDefaultRoute1, UpdateSourceTrigger=PropertyChanged}"
/>
<TextBox
Grid.Row="2"
Grid.Column="1"
Margin="5"
VerticalAlignment="Center"
MaxLength="3"
Width="30"
Foreground="Black"
Opacity="0.8"
Text="{Binding VlanDefaultRoute2, UpdateSourceTrigger=PropertyChanged}"
/>
<TextBox
Grid.Row="2"
Grid.Column="2"
Margin="5"
VerticalAlignment="Center"
MaxLength="3"
Width="30"
Foreground="Black"
Opacity="0.8"
Text="{Binding VlanDefaultRoute3, UpdateSourceTrigger=PropertyChanged}"
/>
<TextBox
Grid.Row="2"
Grid.Column="3"
Margin="5"
VerticalAlignment="Center"
MaxLength="3"
Width="30"
Foreground="Black"
Opacity="0.8"
Text="{Binding VlanDefaultRoute4, UpdateSourceTrigger=PropertyChanged}"
/>
</Grid>
</Grid>
</UserControl>
I want to save multiple values for VLANS values at one time. Now any suggestions?
I think you are looking for a good introduction to get from scratch to an MVVM application that can handle models correctly. In that case I recommend to use a "getting started with MVVM" guid such as this one in Catel.