Slider ValueChanged method command ( MVVM WPF Devexpress ) - c#

I'm trying to bind a method to the value changed of a slider.
I'm using devexpress poco,
XAML:
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Height="140" Margin="20">
<Slider Height="100" Width="40" Margin="5" HorizontalAlignment="Left" TickFrequency="10" TickPlacement="BottomRight" Orientation="Vertical" Minimum="0" Maximum="100" Value="{Binding VolumeLevel}">
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand EventName="ValueChanged" Command="{Binding Path=VolumeChangedCommand}" />
</dxmvvm:Interaction.Behaviors>
</Slider>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
My C# Code:
public void VolumeChanged()
{
...
}
The method never gets called.
Any suggestions?

Because you are binding the slider to a Command (this line: <dxmvvm:EventToCommand EventName="ValueChanged" Command="{Binding Path=VolumeChangedCommand}" />), and you don't have a Command so it won't fire. All you need to do is add a public Command VolumeChangedCommand
private ICommand _VolumeChangedCommand;
public ICommand VolumeChangedCommand
{
get
{
if (_VolumeChangedCommand == null)
_VolumeChangedCommand = new CommandImplement();
return _VolumeChangedCommand ;
}
set
{
_VolumeChangedCommand = value;
}
}
class CommandImplement: ICommand
{
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
VolumeChanged(); //Call your method or put your code here.
}
}

Related

Selecting close button of other tab closes current tab

I am creating an app where new tabs are created dynamically. I have added close button for each tab to close.
Issue:
If I have multiple tabs open, and I am currently in tab2, and I select close button of tab4, then tab2 get closed.
I have also used data binding of my TabControl using RelayCommand. But that also had the same issue.
Kindly suggest where I have gone wrong and what I can add in my code.
Below is my code.
XAML:
<TabControl x:Name="tabControl1" HorizontalAlignment="Stretch" MinHeight="50" Margin="0,0,0,0.2" Width="1215" ItemsSource="{Binding Titles, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Height="454" VerticalAlignment="Bottom">
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="21">
<TextBlock Text="{Binding Header}" />
<Button Name="BtnClose" Content="X" Cursor="Hand" DockPanel.Dock="Right" Focusable="False" FontFamily="Courier" FontSize="9" FontWeight="Bold" Margin="0,1,0,0" Padding="0" HorizontalAlignment="Right" VerticalContentAlignment="Bottom" Width="16" Height="16"
Command="{Binding DataContext.CloseTabCommand,RelativeSource={RelativeSource AncestorType={x:Type Window}}}" CommandParameter="{Binding ElementName=tabControl1,Path=SelectedItem}" />
<!--Click="BtnClose_Click"-->
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<RichTextBox Margin="10" VerticalScrollBarVisibility="Visible">
<FlowDocument>
<Paragraph FontSize="12" FontFamily="Courier New">
<Run Text="{Binding Content}"></Run>
</Paragraph>
</FlowDocument>
</RichTextBox>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
My ViewModel class where I create a class Tab Item "Item" that will hold a tab Content and header.
public class MainWindowViewModel: INotifyPropertyChanged {
public MainWindowViewModel() {
Titles = new ObservableCollection < Item > ();
}
public class Item: INotifyPropertyChanged {
public string Header {
get;
set;
}
//public string Content { get; set; }
private string _content;
public static int _count = -1;
public int Count {
get {
return _count;
}
set {
_count = value; /* OnPropertyChanged(nameof(Count));*/
}
}
public string Content {
get {
return _content;
}
set {
_content = value;
OnPropertyChanged(nameof(Content));
}
}
public Item() {
_count++; //increase the count of tab. This will represent the index of the tab
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName) {
var handler = PropertyChanged;
handler ? .Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public ObservableCollection < Item > Titles {
get {
return _titles;
}
set {
_titles = value;
OnPropertyChanged("Titles");
}
}
static int tabs = 1;
private ObservableCollection < Item > _titles;
private RelayCommand < Item > _closeTabCommand;
public RelayCommand < Item > CloseTabCommand {
get {
return _closeTabCommand ?? (_closeTabCommand = new RelayCommand < Item > (
(t) => {
Titles.Remove(t);
}));
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName) {
var handler = PropertyChanged;
handler ? .Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
MainWindow.xaml.cs
private void BtnClose_Click(object sender, RoutedEventArgs e) {
//remove tab
MainWindowVMObj.RemoveTabItem(tabControl1.SelectedIndex);
}
The close button's CommandParameter is passing the selected tab as the tab to be closed.
One easy fix to that is to simply bypassing the current source control of the event as a CommandParameter instead (which will be the parent TabItem of the targeted close button in that case):
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="21">
<TextBlock Text="{Binding Header}" />
<Button Name="BtnClose" Content="X" Cursor="Hand" DockPanel.Dock="Right" Focusable="False" FontFamily="Courier" FontSize="9" FontWeight="Bold" Margin="0,1,0,0" Padding="0" HorizontalAlignment="Right" VerticalContentAlignment="Bottom" Width="16" Height="16"
Command="{Binding DataContext.CloseTabCommand,RelativeSource={RelativeSource AncestorType={x:Type Window}}}" CommandParameter="{Binding}" />
</StackPanel>
</DataTemplate>

C# UWP: Access a textblock and status of check box inside a listview

Hi I have my list view as follows:
![][1]
<RelativePanel >
<ListView x:Name="StudentListView"
IsItemClickEnabled="True"
Width="1000"
ItemClick="Student_ItemClick" >
<ListView.ItemTemplate>
<DataTemplate x:Name="ABC">
<StackPanel
x:Name="ListItemPanel"
Orientation="Horizontal"
MaxWidth="500">
<TextBlock x:Name ="uName" Text="{Binding Username}"
Margin="20,0,20,8"
FontSize="24"
FontStyle="Italic"
FontWeight="SemiBold"
Foreground="DarkBlue"
/>
<CheckBox Name="AttendCheckBox"
HorizontalAlignment="Left"
Checked="AttendCheckBox_Checked"
IsChecked="False"></CheckBox>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<TextBlock Name="queryName" FontSize="20"></TextBlock>
<Button Name="finishBtn" Content="Finish" RelativePanel.Below="StudentListView" ></Button>
</RelativePanel>
I am trying to access each data item and check if checkbox is checked or not when user clicks on finish button that is on same page as listview. And I am having tough time trying to figure it out. Any hint on it would be great. Thank you
I checked your code. You did not need to use Checked event of CheckBox. Instead, you could declare a bool type property in your custom class and bind IsChecked to it and set Mode=TwoWay, then, once your checkbox's IsChecked value is changed, the source also will be updated. After that, you could filter the source to get the 'IsChecked=True' items.
According to your code snippet, I made a code sample for you reference:
<RelativePanel>
<ListView x:Name="StudentListView"
IsItemClickEnabled="True"
Width="1000" Height="500">
<ListView.ItemTemplate>
<DataTemplate x:Name="ABC">
<StackPanel
x:Name="ListItemPanel"
Orientation="Horizontal"
MaxWidth="500">
<TextBlock x:Name ="uName" Text="{Binding Username}"
Margin="20,0,20,8"
FontSize="24"
FontStyle="Italic"
FontWeight="SemiBold"
Foreground="DarkBlue"/>
<CheckBox Name="AttendCheckBox" HorizontalAlignment="Left" IsChecked="{Binding IsSelected,Mode=TwoWay}"></CheckBox>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<TextBlock Name="queryName" FontSize="20"></TextBlock>
<Button Name="finishBtn" Content="Finish" RelativePanel.Below="StudentListView" Click="{x:Bind finishBtn_Click}"></Button>
</RelativePanel>
public sealed partial class MainPage : Page
{
public ObservableCollection<Test> tests { get; set; }
public MainPage()
{
this.InitializeComponent();
tests = new ObservableCollection<Test>();
for (int i=0;i<100;i++)
{
tests.Add(new Test() {Username="name "+i });
}
StudentListView.ItemsSource = tests;
}
private void finishBtn_Click(object sender, RoutedEventArgs e)
{
var selectedStudents = tests.Where(x => x.IsSelected == true).ToList();
}
}
public class Test : INotifyPropertyChanged
{
private string _Username;
public string Username
{
get { return _Username; }
set
{
if (_Username != value)
{
_Username = value;
RaisePropertyChanged("Username");
}
}
}
private bool _IsSelected;
public bool IsSelected
{
get { return _IsSelected; }
set
{
if (_IsSelected != value)
{
_IsSelected = value;
RaisePropertyChanged("IsSelected");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string PropertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,new PropertyChangedEventArgs(PropertyName));
}
}
}

uwp gridview delete item with button within datatemplate

I have a gridview in UWP app and I have put a button in each gridview item in datatemplate so that it can be used to delete/remove that specific item from the gridview ( removing it from observableCollection behind). I am not using MVVM approach, because I am not much familiar with it, I am using a normal Observable Collection for binding of data and data template.
if you can suggest me a better way to do it, myabe using MVVM please suggest me how to do it. Thanks in advance
Code :
XAML GRID VIEW (button with the red back ground is the button I wanna use to delete item)
<controls:AdaptiveGridView Name="HistoryGridView" StretchContentForSingleRow="False"
Style="{StaticResource MainGridView}"
ItemClick ="HistoryGridView_SelectionChanged"
ItemsSource="{x:Bind HistoryVideos, Mode=OneWay}">
<controls:AdaptiveGridView.ItemTemplate>
<DataTemplate x:DataType="data:Video">
<StackPanel Margin="4" >
<Grid>
<Button Background="Red"
HorizontalAlignment="Right" VerticalAlignment="Top"
Height="36" Canvas.ZIndex="1"
Style="{StaticResource TransparentButton}" Width="36">
<fa:FontAwesome Icon="Close" FontSize="20" HorizontalAlignment="Center" Foreground="White"
/>
</Button>
<Image Canvas.ZIndex="0" Source="{x:Bind Thumbnail}" Style="{StaticResource GridViewImage}"/>
<Border Style="{StaticResource TimeBorder}" Height="Auto" VerticalAlignment="Bottom"
Canvas.ZIndex="1"
HorizontalAlignment="Left">
<TextBlock Text="{x:Bind Duration}" Foreground="White" Height="Auto"/>
</Border>
</Grid>
<TextBlock Text="{x:Bind Name}" Style="{StaticResource GridViewVideoName}"/>
<TextBlock Text="{x:Bind ParentName}" Style="{StaticResource GridViewParentName}"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
<TextBlock Text="{x:Bind Views}" Style="{StaticResource GridViewViews}"/>
<TextBlock Text="Views" HorizontalAlignment="Right"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</controls:AdaptiveGridView.ItemTemplate>
</controls:AdaptiveGridView>
Code Behind
public History()
{
this.InitializeComponent();
HistoryVideos = new ObservableCollection<Video>();
}
public ObservableCollection<Video> HistoryVideos { get; private set; }
I am using onnavigated to method for filling the collection and it works fine and also I guess that is not relevent here.
We can add the Command to the Button to invoke when this button is pressed and we can use parameter to pass to the Command property.
To use the Command, we should be able to define a DelegateCommand class that inherits from the ICommand.
For example:
internal class DelegateCommand : ICommand
{
private Action<object> execute;
private Func<object, bool> canExecute;
public DelegateCommand(Action<object> execute)
{
this.execute = execute;
this.canExecute = (x) => { return true; };
}
public DelegateCommand(Action<object> execute, Func<object, bool> canExecute)
{
this.execute = execute;
this.canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return canExecute(parameter);
}
public event EventHandler CanExecuteChanged;
public void RaiseCanExecuteChanged()
{
if (CanExecuteChanged != null)
{
CanExecuteChanged(this, EventArgs.Empty);
}
}
public void Execute(object parameter)
{
execute(parameter);
}
}
We can add the Id property in the Video, then we can pass the Id property to the CommandParameter. When we click the Button, the ExecuteDeleteCommand method will be fired. We can use the Id to find the Video in the HistoryVideos and use the Remove method to remove it.
The ViewModel code:
internal class ViewModel
{
private ObservableCollection<Viedo> _videos;
public ObservableCollection<Viedo> Videos
{
get
{
return _videos;
}
set
{
if (_videos != value)
{
_videos = value;
}
}
}
public ICommand DeleteCommand { set; get; }
private void ExecuteDeleteCommand(object param)
{
int id = (Int32)param;
Viedo cus = GetCustomerById(id);
if (cus != null)
{
Videos.Remove(cus);
}
}
private Viedo GetCustomerById(int id)
{
try
{
return Videos.First(x => x.Id == id);
}
catch
{
return null;
}
}
public ViewModel()
{
Videos = new ObservableCollection<Viedo>();
for (int i = 0; i < 5; i++)
{
Videos.Add(new Viedo());
Videos[i].Name = "Name";
Videos[i].Id = i;
}
this.DeleteCommand = new DelegateCommand(ExecuteDeleteCommand);
}
}
The XAML code:
<GridView Name="MyGridView" ItemsSource="{Binding Videos}">
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}"></TextBlock>
<Button Background="Red"
HorizontalAlignment="Right" VerticalAlignment="Top"
Height="36" Canvas.ZIndex="1"
Width="36" Command="{Binding DataContext.DeleteCommand, ElementName=MyGridView}" CommandParameter="{Binding Id}">
</Button>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
The code behind:
private ViewModel myViewModel;
public MainPage()
{
this.InitializeComponent();
myViewModel = new ViewModel();
MyGridView.DataContext = myViewModel;
}
Update:
<GridView Name="MyGridView" ItemsSource="{x:Bind myViewModel.Videos}">
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:Viedo">
<StackPanel>
<TextBlock Text="{x:Bind Name}"></TextBlock>
<Button Background="Red"
HorizontalAlignment="Right" VerticalAlignment="Top"
Height="36" Canvas.ZIndex="1"
Width="36" Command="{Binding DataContext.DeleteCommand, ElementName=MyGridView}" CommandParameter="{Binding Id}">
</Button>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>

Why this Button Command Binding is not working?

I did this like 50 times before. I really don't know why it is not working this time. I have a WPF application and my only dependency is MahApps.Metro. I'm using it's MetroWindow and Dynamic Style on my Button.
Here is the latest xaml:
<ItemsControl Grid.Column="0" Grid.Row="1" ItemsSource="{Binding ServerList}" Margin="5">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="LightGray">
<StackPanel Orientation="Horizontal">
<Button Style="{DynamicResource MetroCircleButtonStyle}" Content="{StaticResource appbar_monitor}" Command="{Binding VM.ServerSelectedCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Controls:MetroWindow}}" CommandParameter="{Binding .}"></Button>
<Label Content="{Binding .}" HorizontalAlignment="Center" VerticalAlignment="Center"></Label>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Here is my ServerSelectedCommand in my ViewModel:
private ViewModelCommand _ServerSelectedCommand;
public ViewModelCommand ServerSelectedCommand
{
get
{
if (_ServerSelectedCommand == null)
{
_ServerSelectedCommand = new ViewModelCommand(
p => { SelectServer(p); },
p => true
);
}
return _ServerSelectedCommand;
}
set { _ServerSelectedCommand = value; }
}
private void SelectServer(object parameter)
{
}
ViewModelCommand class is like RelayCommand. Here it is:
public class ViewModelCommand : Observable, ICommand
{
public bool CanExecuteValue
{
get { return CanExecute(null); }
}
public ViewModelCommand(
Action<object> executeAction,
Predicate<object> canExecute)
{
if (executeAction == null)
throw new ArgumentNullException("executeAction");
_executeAction = executeAction;
_canExecute = canExecute;
}
private readonly Predicate<object> _canExecute;
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged;
public void OnCanExecuteChanged()
{
OnPropertyChanged(() => CanExecuteValue);
if (CanExecuteChanged != null)
CanExecuteChanged(this, EventArgs.Empty);
}
private readonly Action<object> _executeAction;
public void Execute(object parameter)
{
_executeAction(parameter);
}
}
Sorry for a lot of code. But I need to add them in order to find the problem which I can't see. So lets turn back to first xaml, that is the latest one I tried. Here are the codes that I tried for problematic Button line.
Command="{Binding ServerSelectedCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ItemsControl}}"
Command="{Binding ServerSelectedCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:ViewModel}}}"
This also doesn't provide anything!
Command="{Binding RelativeSource={RelativeSource AncestorType=Controls:MetroWindow}}"
Thanks!
This binding looks like it is looking for ServerSelectedCommand on the ItemsControl:
Command="{Binding ServerSelectedCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ItemsControl}}"
try this instead:
Command="{Binding DataContext.ServerSelectedCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ItemsControl}}"
Assuming of course that the DataContext of the ItemsControl is your ViewModel.

Leftmouseclick on stackpanel

I have a stackpanel with image and button in it. I want to fire event when user clicks on a button in stackPanel. My code in xaml is
<StackPanel x:Uid="TemperatureMonitor" Orientation="Horizontal" HorizontalAlignment="Left" ToolTip="{DynamicResource InstrumentZweiMesswert}" Height="35">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseLeftButtonDown">
<ei:CallMethodAction TargetObject="{Binding}" MethodName="OnAddUserControl"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Image Width="35" Height="35" x:Uid="Image_15" Source="/Resources\png\TemperatureMonitor.png"/>
<Button x:Uid="TemperatureMonitor" Content="Temperatur Monitor" x:Name="TemperatureMonitor" IsEnabled="True" Width="135"/>
</StackPanel>
And method OnAddUserControl in my viewModel is
public void OnAddUserControl(object sender, RoutedEventArgs e)
{
//some code
}
The problem it that I don't get into OnAddUserControl. Any ideas why?
I want to fire this event when user makes leftMouseClick on a button. So I don't know why, but RelayCommand also doesn't help and not fires method OnAddUserControl. When I moved iteraction code to my button and it looks like this :
<StackPanel Background="Black" x:Uid="TemperatureMonitor" Orientation="Horizontal" HorizontalAlignment="Left" ToolTip="{DynamicResource InstrumentZweiMesswert}" Height="35">
<Image Width="35" Height="35" x:Uid="Image_15" Source="/Resources\png\TemperatureMonitor.PNG"/>
<Button x:Uid="TemperatureMonitor" Content="Temperatur Monitor" x:Name="TemperatureMonitor" IsEnabled="True" Width="135" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseLeftButtonDown">
<ei:CallMethodAction TargetObject="{Binding}" MethodName="OnAddUserControl"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</StackPanel>
i've get during runtime mistake that says "For object Type"DockSite" cannot find methodname "OnAddUserControl"". I will appreciate any ideas or help
You can use RelayCommand for this purpose.
Add RelayCommand.cs to your project.
class RelayCommand : ICommand
{
private Action<object> _action;
public RelayCommand(Action<object> action)
{
_action = action;
}
#region ICommand Members
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
if (parameter != null)
{
_action(parameter);
}
else
{
_action("Hello World");
}
}
#endregion
}
And this is your ViewModel. I called this MainWindowViewModel. So, add MainWindowViewModel.cs class to your solution.
class MainWindowViewModel
{
private ICommand m_ButtonCommand;
public ICommand ButtonCommand
{
get
{
return m_ButtonCommand;
}
set
{
m_ButtonCommand = value;
}
}
public MainWindowViewModel()
{
ButtonCommand=new RelayCommand(new Action<object>(ShowMessage));
}
public void ShowMessage(object obj)
{
MessageBox.Show(obj.ToString());
}
}
And this is your xaml:
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<StackPanel>
<Button Width="220" Content="Click me" Command={Binding ButtonCommand} CommandParameter="StackOverflow" />
</StackPanel>
It will show you messageBox after clicking button. So you change your project for handing Button Click event in this way.

Categories

Resources