Select All in DataGrid from button - c#

I have a little problem about selecting all rows from a DataGrid.
The question is that the CommandButton is in a UserControl which refers to the MainViewModel and the grid is in a UserControl which refers to another ViewModel. The first thought was to make a static method and call it from the mvm, but the datagrid is not static and can't be called. How can i do?
Edit:
I actually solved the problem by rferencing a static instance of the grid from the code behind.
In the pushbutton viewmodel i recalled the select all method inside the command execution
if (_CommandBtnSelectAll == null)
{
// creo una nuova istanza del comando
_CommandBtnSelectAll = new USCommands(
item =>
{
ViewControlCodeBehind.grid.SelectAll();
}
}
In the ViewControl Code Behind i just had to set a static instance of a new DataGrid and assign it the actual datagrid.
public static DataGrid grid;
public ControlBody() // It's the UserControl initialization
{
this.grid = DataGridControl; // DataGridControl is the name of the actual control
}

You could send a message or an event from the view model and subscribe to and handle this event in the view using a messenger or an event aggregator. Please refer to this blog post for more information about this.
The other option would be to inject the view model with an interface that the view implements as suggested here.

Related

How to be get propertychange event from Uc1 to Uc2 on one Windows (WPF)

I have a problem with WPF binding. I have frmBill.xaml Window with two usercontrol like that:
<materialDesign:TransitionerSlide OpeningEffect="{materialDesign:TransitionEffect SlideInFromRight}">
<materialDesign:TransitionerSlide.BackwardWipe>
<materialDesign:SlideWipe Direction="Right"/>
</materialDesign:TransitionerSlide.BackwardWipe>
<materialDesign:TransitionerSlide.ForwardWipe>
<materialDesign:SlideWipe Direction="Left"/>
</materialDesign:TransitionerSlide.ForwardWipe>
<local:ucBill_Information/>
</materialDesign:TransitionerSlide>
</materialDesign:Transitioner>
</Grid>
And I have two ViewModel as ucDeclarationViewModel.cs and ucBill_ViewModel for this. And using Thread with claim based to bind data between this by using a button click event (I got it), but I can not bind data from VM to V (Using prism). I know my issue, but I dont know how to solve it :(. Please help me.
private ucBill_InformationViewModel _ucBlvm;
public ucBill_InformationViewModel ucBIvm { get => _ucBlvm; set => _ucBlvm = value; }
public ucBill_Information()
{
InitializeComponent();
this.DataContext = ucBIvm;
}

Update a combobox from a presenter (MVP)

I am using MVP in my project, but i am new in MVP.
I have two comboboxes. When I select an option in a combobox, the another combobox should be filled with new data.
This action will be in Presenter. I get my view 'view1' in Presenter, and introduced Combobox1 and Combobox2 as properties in 'view1', because I need 'DataSource', 'DisplayMember', 'ValueMember' and 'Refresh()' in the method below.
But, when using a pattern, it is enough to send a property like
public string Combobox2
{
get { return comboBox1.SelectedValue.ToSstring(); }
}
into Presenter not the whole Combobox. How can I solve this problem?
public void OnSelectedIndexChangedCombobox1()
{
if (view1.Combobox1.SelectedIndex == -1)
{
return;
}
DataTable dt = Tools.GetDataTable("A Path");
var query =
(from o in dt.AsEnumerable()
where o.Field<string>("afield") ==
farmerView.Combobox1.SelectedValue.ToString()
orderby o.Field<string>("anotherfield")
select new KeyValuePair<string, string>(o.Field<string>("field1"),
o.Field<string>("field2"))).ToList();
farmerView.Combobox2SelectedIndexChanged -= OnSelectedIndexChangedCombobox2;
farmerView.Combobox2.DataSource = new BindingSource(query, null);
farmerView.Combobox2.DisplayMember = "Value";
farmerView.Combobox2.ValueMember = "Key";
farmerView.Combobox2.Refresh();
farmerView.Combobox2SelectedIndexChanged +=
OnSelectedIndexChangedCombobox2;
farmerView.Combobox2.SelectedIndex = -1;
}
Thank you
You should not pass any Android objects to presenter, just get the event in view (for instance your Activity) then call a method from presenter that provides data for second ComboBox (we call it Spinner in Android!) by passing selected item from first one, and then presenter will call a method of View which fill the second one and View knows how to do it.
You can take a look at this sample project http://github.com/mmirhoseini/marvel and this article https://hackernoon.com/yet-another-mvp-article-part-1-lets-get-to-know-the-project-d3fd553b3e21 to get more familiar with MVP.

Bubbling up a button command in UserControl

I have a button in a user control called LauncherView + LauncherViewModel, I add this to the main window called MainView + MainViewModel.
When I click on the button I would like to capture the event in the MainViewModel. How can I do this?
In the LauncherViewModel is easy enough with:
RelayCommand launchCommand;
public ICommand LaunchCommand{
get{
if (launchCommand == null){
launchCommand = new RelayCommand(LaunchCommandExecute, CanLaunchCommandExecute);
}
return launchCommand;
}
}
private void LaunchCommandExecute(object parameter){
//Do something to recognize the button.
//Could use ObservableCollection<Module> module_objects
//to match, if I could get the buttons content or name
}
private bool CanLaunchCommandExecute(object parameter){
return true;
}
However tried this in the MainViewModel as well hoping for a bubbling effect to occur, no such luck unfortunately.
You can do this by using a RoutedCommand instead of a RelayCommand.
Alternatively, your ViewModel could raise an event, to which the parent (MainViewModel) could subscribe. When the button is pressed, you could simply raise the event.
Change LaunchCommand to a dependency property and then bind that to your MainWindow's command in the XAML where you declare the LauncherView.

Adding UserControl to a Canvas by a Command in ViewModel in WPF

I have a UserControl say Stock and it has a Button called Display
<Button Command="{Binding DisplayCommand}" CommandParameter="StockGroups">Display</Button>
Now when i Click this button it should add an another UserControl named Display to the Canvas which is in HomeWindow and should pass the CommandParameter to the Display userControl.
private DelegateCommand<string> _displayCommand;
public virtual void DisplayExecuted(string param){}
public ICommand DisplayCommand
{
get
{
if (_displayCommand == null)
_displayCommand = new DelegateCommand<string>(new Action<string>(DisplayExecuted));
return _displayCommand;
}
}
An alternative method which is more MVVM-ish would be to have a boolean property named ShouldDisplayControl, which is then bound to the control's Visibility property (using the [BooleanToVisibilityConverter]) 1), while passing the CommandParameter as a second property, maybe ControlParameter, which the control is also bound to.
This is not an operation that should involve the ViewModel, since it does not manipulate any model data.
Instead of a ViewModel command, consider merely handling the button's OnClick in the code-behind of the xaml.
In your HomeWindow.xaml.cs file:
protected override void Display_OnClick(object sender, EventArgs e) {
var buttonName = ((Button)sender).Name; // gets the name of the button that triggered this event
var displayControl = new DisplayControl(); // your user control
displayControl.param = buttonName; // set the desired property on your display control to the name of the button that was clicked
((Canvas)Content).Children.Add(displayControl); // 'Content' is your Canvas element
}
And in your HomeWindow.xaml file:
<Button x:Name="StockGroups" Click="Display_OnClick" Text="Display" />
That should get you what you want, without needing to create and invoke a command in the viewmodel. The name of the clicked button will be set to the specified property in your userControl, and an instance of the control will be created inside the Canvas.

Sharing non control related data between WPF ViewModel and UserControl

I'm new to WPF and the MVVM pattern so keep that in mind.
The project I'm tasked with working on has a view and a view model. The view also contains a user control that does NOT have a view model. There is data (custom object ... Order) being passed to the view model that I also need to share with the user control.
It looks like the UserControl does share data between the view model already via DependencyPropertys but this data is just text boxes on the user control that look to be bound back to propertys on the view model.
I need to share data that will NOT be represented by a control on the user control. Is there a good way to pass this data (complex Order object)? Maybe I do need some kind of hidden control on my user control to accomplish this but I'm just not that sure being new to this. Any advice would be appreciated.
There is no need for hidden fields (or any such concept in WPF) as you can add any custom properties you want to a user control.
In the user control, create a new dependancy property like this but with MyUserControl set apropriately:
public Order CurrentOrder
{
get { return (Order)GetValue(CurrentOrderProperty); }
set { SetValue(CurrentOrderProperty, value); }
}
// Using a DependencyProperty as the backing store for CurrentOrder. This enables binding, etc.
public static readonly DependencyProperty CurrentOrderProperty =
DependencyProperty.Register("CurrentOrder", typeof(Order), typeof(MyUserControl), new PropertyMetadata(null, OnCurrentOrderPropertyChanged));
public static void OnCurrentOrderPropertyChanged(DependencyObject Sender, DependencyPropertyChangedEventArgs e)
{
var sender = Sender as MyUserControl;
var NewValue = e.NewValue as Order;
var OldValue = e.OldValue as Order;
if (OldValue != null && sender != null)
{
//Use old value as needed and use sender instead of this as method is static.
}
if (NewValue != null && sender != null)
{
//Use new value as needed and use sender instead of this as method is static.
}
}
In you're parent view where you use the usercontrol you then write something like:
<local:MyUserControl CurrentOrder="{Binding ViewModelOrder}" />
Where CurrentOrder is the dependancy property on the usercontrol and ViewModelOrder is the name of the property in the view model you would need to replace local:MyUserControl with your control name/namespace.
You can simply create a dependency property in the class of your UserControl and bind to it in the View that uses the control. There is no need to internally bind the dependency property to one of the controls in the UserControl.

Categories