Not too sure what I am missing here, but I have a few comboBoxes in a form and I would like to hit a "Clear" button and reset all the values to the original SelectedItem value.
xml:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="213" Width="513">
<Grid>
<ComboBox x:Name="cbox_Values" HorizontalAlignment="Left" Margin="247,77,0,0" VerticalAlignment="Top" Width="120">
<ComboBoxItem IsSelected="True">Value1</ComboBoxItem>
<ComboBoxItem>Value2</ComboBoxItem>
<ComboBoxItem>Value3</ComboBoxItem>
</ComboBox>
<Button x:Name="btn_Clear" Content="Clear" HorizontalAlignment="Left" Margin="115,77,0,0" VerticalAlignment="Top" Width="86" Height="21" FontSize="11"/>
</Grid>
</Window>
If I do it this way:
$wpf_btn_Clear.Add_Click({
$wpf_cbox_Values.SelectedItem.Content = "Value1"
})
The current value gets wiped:
If I do it this way:
$wpf_btn_Clear.Add_Click({
$wpf_cbox_Values.SelectedItem.Content = "Value1"
$wpf_cbox_Values.Items.Add("Value2")
$wpf_cbox_Values.Items.Add("Value3")
})
I get doubles:
I am looking for the button to "reset" the comboBox with the original IsSelected item from the xml. For example, if i select Value3, then click the "Clear" button, the value goes back to Value1. This is in Powershell.
$wpf_cbox_Values.SelectedIndex = 0 and/or $wpf_cbox_Values.SelectedItem = $wpf_cbox_Values.Items[0] should work.
ComboBox.SelectedIndex Property
Perhaps try...
$wpf_btn_Clear.Add_Click({
$wpf_cbox_Values.SelectedIndex = 0
})
Should keep your values, but set combobox index to zero which would be your first entry ("Value1").
Related
How to get selected Cell value from Datagrid?
What information i have looked? Everything where title was "WPF get cell value MVVM".
What i did? 1 step:
<Page x:Class="PDB.UsersView"
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:PDB"
xmlns:PDB ="clr-namespace:PDBapi;assembly=PDBapi"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="UsersView"
>
<Page.DataContext>
<PDB:UsersViewModel/>
</Page.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--Page Header info content-->
<Grid Grid.Row="0">
<TextBlock Text="{Binding ElementName=myGrd, Path=CurrentCell.Column.DisplayIndex}"/>
</Grid>
<!--Datagrid content-->
<DataGrid x:Name="myGrd"
SelectionMode="Single"
SelectionUnit="Cell"
IsReadOnly="True"
Grid.Row="1"
ItemsSource="{Binding Users}"
AutoGenerateColumns="True"
CanUserAddRows="False">
<DataGrid.InputBindings>
<MouseBinding MouseAction="RightClick"
Command="{Binding CellClickCommand}"
CommandParameter="{Binding ElementName=myGrd, Path=CurrentCell}" />
</DataGrid.InputBindings>
</DataGrid>
</Grid>
</Page>
VM:
public UsersViewModel()
{
UserList = new ObservableCollection<User>();
GetUsers();
Users = CollectionViewSource.GetDefaultView(UserList);
CellClickCommand = new RelayParamCommand((data) => GetValue(data));
}
public void GetUsers()
{
User user = new User();
// Users = await user.GetUsers();
UserList.Add(new User
{
Name = "Marius",
Departament = "some",
Tabelis = 5
});
UserList.Add(
new User
{
Name = "Darius",
Departament = "unknown",
Tabelis = 20
});
}
private void GetValue(object data)
{
var some = (DataGridCellInfo)data;
//Returns only number
Console.WriteLine(some.Column?.DisplayIndex.ToString());
}
}
But with this approach i faced 2 issues:
In xaml page i added textblock for testing which text was binded to datagrid currentCell. When i click right mouse button it shows int value correctly. But in my GetValue(object data) function console return null at first right click and from second time returns int value, but value in console is always diferent from textblock value, i have to click two times on same cell to get right cell position. That is completly wrong. How to solve that?
Another issue: How to get real value from currentCell i have binded?
What i did? 2 step:
In xaml i binded datagrid currentCell to VM property CurrentCell="{Binding Cell}"
I got value it was ok, but still it returns only DataGridCellInfo object. I tried to cast to Users object and various things but i failed to get value of cell.
Can someone provide good practice to get cell value from datagrid?
The data grid is bound to a collection of users, so each user is represented by one row, not one cell. That's why CurrentCell returns a DataGridCellInfo
If you want the user, bind to CurrentItem instead.
In XAML:
<DataGrid
ItemsSource="{Binding Users}"
CurrentItem="{Binding SelectedUser}"...
In the view model:
private user selectedUser;
public user SelectedUser
{
get => selectedUser;
set
{
var u = value as user;
selectedUser = u;
}
}
I have a very simple sample code, a TextBox and a Button. User inputs some text in textBox and click the Button. It should show a common MessageBox which contains the text he just input in the TextBox.
Problem: the MessageBox shows blank! After some trial and error I found out the reason. I set in .xaml the Focusable of Button as false. Why? Because I want to stop the blinking effect of button after it is clicked once.
So I have an idea. I bind the Focusable to a property in ViewModel and initialized in constructor (or in private field as initial value) of ViewModel as false. Then in the Button-Click event handler before showing MessageBox I set the property to true and then after executing MessageBox set it to false again. Problem: Unfortunately, it doesn't work! It seems the Focusable can only be set once in constructor or in private field as initial value.
Does someone know how to solve this problem? I want to keep the Focusable of the Button to false (to avoid the Button blinking) and I want to get the text from TextBox by clicking the Button. Following is the sample code and feel free to modify and show me the solution. Thank you in advance.
XAML / View
<Grid Width="300" Height="300">
<StackPanel VerticalAlignment="Center">
<TextBox Width="150" Text="{Binding Path=MyText}" />
<Button x:Name="ShowText"
Width="100"
Content="Show Text"
Focusable="{Binding Path=MyFocus}" />
</StackPanel>
</Grid>
View model
public class ShellViewModel : PropertyChangedBase
{
private String _myText;
public String MyText
{
get { return _myText; }
set
{
_myText = value;
NotifyOfPropertyChange(() => MyText);
}
}
private Boolean _myFocus = false; // if it is true, the MessageBox can show MyText, otherwise MessageBox shows blank
public Boolean MyFocus
{
get { return _myFocus; }
set
{
_myFocus = value;
NotifyOfPropertyChange(() => MyFocus);
}
}
public void ShowText()
{
//MyFocus = true; // this doesn't work
MessageBox.Show(MyText);
//MyFocus = false; // this doesn't work
}
}
<Grid Width="300" Height="300">
<StackPanel VerticalAlignment="Center">
<TextBox Width="150" Text="{Binding MyText, Mode=TwoWay}" />
<Button x:Name="ShowText"
Width="100"
Content="Show Text"
Focusable="{Binding MyFocus}" />
</StackPanel>
</Grid>
or
<Grid Width="300" Height="300">
<StackPanel VerticalAlignment="Center">
<TextBox Width="150" x:Name="MyText" />
<Button x:Name="ShowText"
Width="100"
Content="Show Text"
Focusable="{Binding MyFocus}" />
</StackPanel>
</Grid>
that should work either way, the way you did the binding wouldn't ever update the underlying property since it wasn't considered bi-directional. Therefore Mode=TwoWay was necessary on the 1st version, the second version uses CM's conventions to find the the textbox and bind it to a property of the same name on the viewmodel.
not sure what blinking your referring to the default style doesn't have a blink... at least not on windows 8.1 or windows 10. The only thing focusable does in the regard of the code frag you did was prevent keyboard access..
I have three Text Box called TxtDocumentTitle1, TxtDocumentTitle2,TxtDocumentTitle3 lastly there is a Add More Button. Client can Click Add more Button so that it generates Text box naming TxtDocumentTitle4. If more needed he/she can Add more Text Boxes.
Sample XAML code of View
<Grid Height="450" Width="700" Background="White">
<TextBlock Height="23" HorizontalAlignment="Left" Margin="67,20,0,0" Name="textBlocKname" Text="Document Title1:" VerticalAlignment="Top" Width="110" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="67,87,0,0" Name="textBlockAddress" Text="Document Title2:" VerticalAlignment="Top" Width="110" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="67,154,0,0" Name="textBlockCompanyName" Text="Document Title3:" VerticalAlignment="Top" Width="110" />
<TextBox Height="46" Margin="67,37,87,0" Name="txtDocumentTitle1" VerticalAlignment="Top" FontSize="24" />
<TextBox Height="46" HorizontalAlignment="Left" Margin="67,106,0,0" Name="txtDocumentTitle3" VerticalAlignment="Top" Width="546" FontSize="24" />
<TextBox Height="46" HorizontalAlignment="Left" Margin="67,171,0,0" Name="txtDocumentTitle2" VerticalAlignment="Top" Width="546" FontSize="24" />
<Button Content="Add More" Height="37" HorizontalAlignment="Right" Margin="0,223,87,0" Name="btnAddmore" VerticalAlignment="Top" Width="102" />
</Grid>
You can achieve this easily via Binding. if your Window does not have a ViewModel open your window's xaml.cs and make it like this:
public Window1()
{
InitializeComponent();
DataContext = this;
}
public ObservableCollection<TextBoxVm> Items { get { return _items; } }
private ObservableCollection<TextBoxVm> _items = new ObservableCollection<TextBoxVm>();
if not, just add the two last lines to the viewModel of your window.
Now you need to define a class derived from DependencyObject and name it say TextBoxVm. create two DependencyPropertys in it (use propdp snippet) as follows:
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(TextBoxVm), new UIPropertyMetadata("default text",
(d,e)=>
{
var vm = (TextBoxVm)d;
var val = (string)e.NewValue;
MyDataService.FindAndUpdateItemInDatabase(vm.Id, val);//you can access database with something like this
}));
public string TitleText
{
get { return (string)GetValue(TitleTextProperty); }
set { SetValue(TitleTextProperty, value); }
}
public static readonly DependencyProperty TitleTextProperty =
DependencyProperty.Register("TitleText", typeof(string), typeof(TextBoxVm), new UIPropertyMetadata("default title"));
This would be the xaml code:
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="{Binding TitleText}"/>
<TextBox Text="{Binding Text}"/>
</WrapPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Now the only thing left is to write Button logic. simply add TextBoxVm to Items when Button is clicked.
Items.Add(new TextBoxVm {
TitleText = string.Format("Document Title{0}:", Items.Count+1)
});
Edit Note:
this approach is standard MVVM (expect for the button click event, which should be done using Command). So if you want to add controls in code (which is not recommended) search this :
add control to wpf grid programmatically.
*Above Answer from Bizz Gives Solution of My Question * Beside that it Rise me a Question about *DependencyObject * after Few Research i found this about Dependancy Object which may be Helpful for New comer to WPF like me :)
What is DependencyObject??
Dependency object is the base object for all WPF objects. All the UI Elements like Buttons TextBox etc and the Content Elements like Paragraph, Italic, Span etc all are derived from Dependency Object.
Dependency objects are used for WPF property system. By default, what ever the property system we have in DOT Net CLR is very basic. But Dependency properies provide lots of addtional features/services to support Data Binding.
Once you create any property as a dependency property, then automatically you get following feature implemented for you. ie. Change Notification, Validation, Call Back, Inheritance, DataBinding, Styles, Default Values etc.
If you need to implement all these features on your own for all properties where you need these feature, then it will be a big process and head ache for you. So, these all coming out of the box from Dependency Object class.
Basically dependency object class contains a dictionary. So, when ever set any value or retrieve value, then it will change the value or read from that Dictionary. So, it is nothing but a key value pair.
For Detail Info abouT DependencyObject
http://www.codeproject.com/Articles/140620/WPF-Tutorial-Dependency-Property
http://www.pinfaq.com/32/what-is-dependency-object-in-wpf-where-should-i-use-it
I have used tab control for view my usercontrols..
in 1st usercontrol
I have used datagrid to diplay Record and for Binding I have used generic List.
When want to change this List as per selected date then that collection is changed in database and in viewmodel also as List's set propery get executes but in view when i selected new tab and then go back to prevois tab at that time List's get property executes & then i am able get view as per selected date.
My main view and which contain 1st usercontrol as 1st tab item is given below:
Xaml code for above view is given below:
<DataGrid
Background="Transparent"
CanUserAddRows="True"
CanUserReorderColumns="False"
ItemsSource="{Binding Model_Transactions_TransactionsDetails_Jama,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
HeadersVisibility="Column">
</DataGrid>
<Grid DockPanel.Dock="Bottom" VerticalAlignment="Bottom" >
<Border BorderBrush="Black" BorderThickness="1" >
<Label HorizontalAlignment="Left" HorizontalContentAlignment="Right" Width="75" Content="{Binding SumOfWeightJama,UpdateSourceTrigger=PropertyChanged}" FontFamily="Segoe UI" FontWeight="Bold" FontSize="16" />
</Border>
</Grid>
<DataGrid
Background="Transparent"
CanUserAddRows="True"
CanUserReorderColumns="False"
ItemsSource="{Binding Model_Transactions_TransactionsDetails_Udhar,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
HeadersVisibility="Column">
</DataGrid>
<Grid DockPanel.Dock="Bottom" VerticalAlignment="Bottom">
<Border BorderBrush="Black" BorderThickness="1">
<Label Width="75" HorizontalAlignment="Left" HorizontalContentAlignment="Right" Content="{Binding SumOfWeightUdhar,UpdateSourceTrigger=PropertyChanged}" FontFamily="Segoe UI" FontWeight="Bold" FontSize="16"/>
</Border>
</Grid>
And View Model for above View is given below:
private DateTime _FilterDate ;
public DateTime FilterDate
{
get
{
return _FilterDate;
}
set
{
_FilterDate = value;
OnPropertyChanged("FilterDate");
Model_Transactions_TransactionsDetails_Jama = (ViewModel.AllDataCollactions.AllTransactionsDetails.Where(s => s.TransactionDate.Equals(FilterDate) && s.IsJama).OrderBy(s => s.TransactionsID)).ToList();
Model_Transactions_TransactionsDetails_Udhar = (ViewModel.AllDataCollactions.AllTransactionsDetails.Where(s => s.TransactionDate.Equals(FilterDate) && !s.IsJama).OrderBy(s => s.TransactionsID)).ToList();
}
}
public List<Model_TransactionsDetails> Model_Transactions_TransactionsDetails_Jama
{
get
{
return model_Transactions_TransactionsDetails_Jama;
}
set
{
model_Transactions_TransactionsDetails_Jama = value;
OnPropertyChanged("Model_Transactions_TransactionsDetails_Jama");
}
}
public List<Model_TransactionsDetails> Model_Transactions_TransactionsDetails_Udhar
{
get
{
return model_Transactions_TransactionsDetails_Udhar;
}
set
{
model_Transactions_TransactionsDetails_Udhar = value;
OnPropertyChanged("Model_Transactions_TransactionsDetails_Udhar");
}
}
public ViewModel_MasterBook()
{
FilterDate = DateTime.Now.AddDays(-1).Date;
InsertCommand = new RelayCommand(AddExecute, CanAdd);
}
Can any one help me How can i get view as per selected date immediately..
actually it should work i cant see an error. but when i use some kind of Lists in my WPF projects i use observablecollection with clear, add, delete.
but first i would change the binding
ItemsSource="{Binding Model_Transactions_TransactionsDetails_Jama,Mode=OneWay}"
because Mode=TwoWay makes no sense, you never set the itemssource from your datagrid to the viewmodel.
second i would change to ObservableCollection
public ObservableCollection<Model_TransactionsDetails> Model_Transactions_TransactionsDetails_Jama
{
get; private set;
}
with private setter because just initialize once.
//ctor
this.Model_Transactions_TransactionsDetails_Jama = new ObservableCollection<Model_TransactionsDetails>();
and then in your FilterDate setter fill the collection
this.Model_Transactions_TransactionsDetails_Jama.Clear();
var newdata = (ViewModel.AllDataCollactions.AllTransactionsDetails.Where(s => s.TransactionDate.Equals(FilterDate) && s.IsJama).OrderBy(s => s.TransactionsID)).ToList();
this.Model_Transactions_TransactionsDetails_Jama.AddRange(newdata);//AddRange is simply an extension method i wrote, you can simply use foreach and .Add()
I have Two radio buttons. If i check first radio button The below data will populate in the combobox. After that i will check another radio button, i want to clear the combo box values.
<RadioButton Height="29"
HorizontalAlignment="Left"
Margin="143,193,0,0" Name="rdoEmployee" VerticalAlignment="Top" Width="61"
FontSize="20" Checked="rdoEmployee_Checked" GroupName="rdoEmployee/>
<RadioButton FontSize="20" Height="20" Margin="228,193,0,0" Name="rdoPA"
VerticalAlignment="Top" HorizontalAlignment="Left" Width="49"
Checked="rdoPA_Checked" GroupName="rdoEmployee />
<ComboBox HorizontalAlignment="Left" Margin="142,235,0,240"
Name="cmbEmpType" Width="200" FontSize="16" />
EmployeeTypes _ET = new EmployeeTypes();
DataRowCollection drc = _ET.EmpTypeTable.Rows;
foreach (DataRow r in drc)
{
ComboBoxItem item = new ComboBoxItem();
item.Tag = r["EmpTypeID"];
item.Content = r["EmpTypeName"];
cmbEmpType.Items.Add(item);
if (cmbEmpType.Items.Count > 0)
{
cmbEmpType.SelectedIndex = 0;
}
}
Are you asking for
cmbEmpType.Items.Clear();
This should empty your combo.
Is it bound? If so, set the bound property to null. If not, set SelectedItem to null.