NumericUpDown value binding - c#

I have a problem. How to bind a ItemsSource property to a NumericUpDown? This way it does not work. Thx!
<DataGrid ItemsSource="{Binding Articles}">
<DataGrid.Columns>
<DataGridTemplateColumn MinWidth="100"
Header="Amount"
MaxWidth="{Binding MinWidth, RelativeSource={RelativeSource Self}}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<mahApps:NumericUpDown Value="{Binding Amount, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="ValueChanged">
<i:InvokeCommandAction CommandParameter="{Binding}"
Command="{Binding DataContext.RefreshValuesCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</mahApps:NumericUpDown>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
EDIT
FIRST: Cantidad (Spanish) = Amount (English)

If the Amount property is defined in the same class as the Articles property you should bind to the DataContext (DataContext.Amount) of the DataGrid:
<mahApps:NumericUpDown Value="{Binding DataContext.Amount, UpdateSourceTrigger=PropertyChanged,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="ValueChanged">
<i:InvokeCommandAction CommandParameter="{Binding}"
Command="{Binding DataContext.RefreshValuesCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</mahApps:NumericUpDown>
If the Amount property is defined in the data object (Article or whatever you call it) class it is simply:
<mahApps:NumericUpDown Value="{Binding Amount}">
Edit: You should also set the UpdateSourceTrigger of the Binding to PropertyChanged:
<mahApps:NumericUpDown Value="{Binding Amount, UpdateSourceTrigger=PropertyChanged}" />

Related

C# wpf Databinding command not working in contextmenu

I am learning wpf and mvvm and I decided to create a Soundboard for myself to practice and so far it's going pretty well.
Now I have made a datatemplate where for every file that the program finds in the specified directory it will create a button with the name of the file in it and I can click it to play. So far so good.
However I now tried to make a ContextMenu so that when I want to remove a file from the list I can right click and select remove, but this command doesn't work even though I have the exact same command structure for the regular button.
I am really quite confused with the whole RelativeSource thing and was already happy my regular 'play' command worked in the button.
If someone could point me in the right direction that would be great. I really could use an explanation on my specific problem as that always seems to help me more then a generic example somehow. I have tried to read on all the related questions but just don't seem to figure it out from there.
My ItemsControl:
<ItemsControl x:Name="MySounds" ItemsSource="{Binding Sounds}">
ItemTemplate:
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<Button Style="{StaticResource mainButton}"
Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.PlaySound}"
CommandParameter="{Binding Path=Tag, RelativeSource={RelativeSource Self}}"
Tag="{Binding Path=Name}">
<TextBlock Text="{Binding Path=NormalizedName}" TextWrapping="Wrap" Height="auto" />
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="{Binding Path=Name}"
Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.RemoveSound}"
CommandParameter="{Binding Path=Tag, RelativeSource={RelativeSource Self}}">
<MenuItem.Icon>
<Image Source="\WpfPractice;component\Images\CoffeeArt.png" Width="20" VerticalAlignment="Center"/>
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</Button.ContextMenu>
</Button>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
I have a generic RelayCommand in my viewmodel and that all works, the problem really is just with the binding.
If you bind the Tag property of the Button to the ItemsControl, you could bind to the command using the PlacementTarget property of the ContextMenu:
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<Button Style="{StaticResource mainButton}"
Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.PlaySound}"
CommandParameter="{Binding Path=Name}"
Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}}">
<TextBlock Text="{Binding Path=NormalizedName}" TextWrapping="Wrap" Height="auto" />
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="{Binding Path=Name}"
Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.Tag.DataContext.RemoveSound}"
CommandParameter="{Binding Path=Name}">
<MenuItem.Icon>
<Image Source="\WpfPractice;component\Images\CoffeeArt.png" Width="20" VerticalAlignment="Center"/>
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</Button.ContextMenu>
</Button>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
You can try to replace your command string in your MenuItem by this :
Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.RemoveSound}"

KeyBinding Label

I have a TreeView with the following definition:
<TreeView ItemsSource="{Binding Folders, UpdateSourceTrigger=PropertyChanged}" x:Name="tree">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Folders, UpdateSourceTrigger=PropertyChanged}">
<Label Content="{Binding Name}" >
<Label.InputBindings>
<KeyBinding Key="Delete"
Command="{Binding DataContext.DeleteFolderCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"/>
<MouseBinding MouseAction="LeftDoubleClick"
Command="{Binding DataContext.SelectFolderCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
CommandParameter="{Binding ElementName=tree, Path=SelectedItem}" />
</Label.InputBindings>
</Label>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
This view is boud to it's Code-Behind-File with:
DataContext="{Binding RelativeSource={RelativeSource Self}}"
The InputBinding for the LeftDoubleClick just works fine.
But the InputBinding for the 'Delete'-Key doesn't work.
The Command where the KeyBinding is bound to looks like:
public ICommand DeleteFolderCommand
{
get { return _deleteFolderCommand; }
set
{
_deleteFolderCommand = value;
OnPropertyChanged();
}
}
and in the constructor I define:
DeleteFolderCommand = new RelayCommand(DeleteFolder);
and the DeleteFolder-Method just looks like:
private void DeleteFolder(object parameter)
{
// Break-Point here will not be reached
}
What am I doing wrong?
I've already checked the Output-Window for Binding-Errors, but there are none.
I managed it by handling the KeyBinding directly at the TreeView
<TreeView ItemsSource="{Binding Folders, UpdateSourceTrigger=PropertyChanged}" x:Name="tree">
<TreeView.InputBindings>
<KeyBinding Key="Delete" Command="{Binding DataContext.DeleteFolderCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"/>
</TreeView.InputBindings>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Folders, UpdateSourceTrigger=PropertyChanged}">
<Label Content="{Binding Name}">
<Label.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick"
Command="{Binding DataContext.SelectFolderCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
CommandParameter="{Binding ElementName=tree, Path=SelectedItem}" />
</Label.InputBindings>
</Label>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>

Display Text in the Combobox

I have an wpf application.I want to show the selected item in the Combo box.
I get an error saying Cant use both DisplayMemberPath and Item Template.
My ItemsSource is not of string type
its a class called "StockExchange"
Following is my code :
<telerik:RadComboBox Grid.Column="1" DisplayMemberPath="StockExchangeName" Name="cmbStockExchange" Foreground="White" HorizontalAlignment="Left" HorizontalContentAlignment="Center" Margin="118,14,0,0" VerticalAlignment="Top" Width="100" Height="23" ItemsSource="{Binding StockExchange, Mode=TwoWay}" SelectedItem="{Binding SelectedStockExchange,Mode= TwoWay}" telerik:StyleManager.Theme="Summer" TabIndex="3">
<telerik:RadComboBox.ItemTemplate >
<DataTemplate>
<CheckBox Name="StockExchange" Content="{Binding StockExchangeName}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<Commands:EventToCommand Command="{Binding DataContext.StockExchangeCheckedCmd,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type telerik:RadWindow}}}" CommandParameter="{Binding ElementName=StockExchange}" ></Commands:EventToCommand>
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<Commands:EventToCommand Command="{Binding DataContext.StockExchangeUnCheckedCmd,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type telerik:RadWindow}}}" CommandParameter="{Binding ElementName=StockExchange}" ></Commands:EventToCommand>
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
</DataTemplate>
</telerik:RadComboBox.ItemTemplate>
</telerik:RadComboBox>
what is solution for this? how can I display single or multiple selected Items in a Combo box?
<telerik:RadComboBox Grid.Column="1" Name="cmbStockExchange" Foreground="White" HorizontalAlignment="Left" HorizontalContentAlignment="Center" Margin="118,14,0,0" VerticalAlignment="Top" Width="100" Height="23" ItemsSource="{Binding StockExchange, Mode=TwoWay}" SelectedItem="{Binding SelectedStockExchange,Mode= TwoWay}" telerik:StyleManager.Theme="Summer" TabIndex="3">
<telerik:RadComboBox.ItemTemplate >
<DataTemplate>
<CheckBox Name="StockExchange" Content="{Binding StockExchangeName}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<Commands:EventToCommand Command="{Binding DataContext.StockExchangeCheckedCmd,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type telerik:RadWindow}}}" CommandParameter="{Binding ElementName=StockExchange}" ></Commands:EventToCommand>
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<Commands:EventToCommand Command="{Binding DataContext.StockExchangeUnCheckedCmd,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type telerik:RadWindow}}}" CommandParameter="{Binding ElementName=StockExchange}" ></Commands:EventToCommand>
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
</DataTemplate>
</telerik:RadComboBox.ItemTemplate>
Create a Textblock that Shows the selected item StockExchangeName
<TextBlock Text="{Binding Path=SelectedItem.StockExchangeName, ElementName=cmbStockExchange}" />
If you select CheckBox, no item is shown selected in comboBox because no item is selected since click event is handled by checkbox.
You can bind IsChecked with IsSelected value of ComboBoxItem so that on click of checkbox corresponding item gets selected.
<CheckBox Content="{Binding StockExchangeName}"
IsChecked="{Binding IsSelected, RelativeSource={RelativeSource
Mode=FindAncestor, AncestorType=ComboBoxItem}}"/>
This will show checkBox in comboBox because you have provided template with checkBox in it for comboBoxItem.

Capture Label text from DataGrid in MVVM WPF

I have implemented a Label in DataGrid using MVVM. My requirement is when user clicks on the Label the events need to be raised which is working fine. But now I would like to capture the label text, but I am unable to acheive this:
<DataGrid HorizontalAlignment="Stretch" Name="DgPreviousEntries" HeadersVisibility="None"
ItemsSource="{Binding WeeklyWiseEntries}" AutoGenerateColumns="False" SelectedItem="{Binding SelectedweekEntry}">
<DataGrid.Columns>
<DataGridTemplateColumn IsReadOnly="True" Width="600">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<Grid>
<Label Grid.Column="0" Grid.Row="1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}, Path=DataContext.WeekCommand}">
</i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
<Label.Content>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="Mon
{0}">
<Binding Path="Monday" Source="Monday" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Label.Content>
</Label>
</Grid>
</StackPanel>
<DataTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataGrid.Columns>
</DataGrid>
Did you try passing the Label Text as Command Paramter?
CommandParameter={Binding Path=Content, ElementName=LabelName}
E.g:
<Label Grid.Column="0" Grid.Row="1" Name="DayLabel">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<i:InvokeCommandAction
Command="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}, Path=DataContext.WeekCommand}"
CommandParameter={Binding Path=Content, ElementName=DayLabel}>
</i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
<Label.Content>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="Mon
{0}">
<Binding Path="Monday" Source="Monday" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Label.Content>
</Label>

Styling custom control

I made my own controls. One inherits from DataGrid and the another from ContentControl. One of them gets the other so I try to expose their properties but as I need many different controls I want to make a Style for my control (the one that inherit from DataGrid) and set the properties from this control to my ContentControl. I just wrote the code like this but it does not work. Any body knows what I am doing wrong?
<Style x:Key="CustomDataGridStyle"
TargetType="{x:Type controls:CustomDataGrid}">
<Setter Property="CurrentRow"
Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type controls:DataGridContainer}}, Path=SelectedItem, Mode=TwoWay}" />
<Setter Property="CaptionVisibility"
Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type controls:DataGridContainer}}, Path=CaptionVisibility, Mode=TwoWay}" />
<Setter Property="CaptionText"
Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type controls:DataGridContainer}}, Path=CaptionText, Mode=TwoWay}" />
<Setter Property="RowValidationErrorTemplate"
Value="{StaticResource BasicRowValidationErrorTemplate}" />
<Setter Property="CurrentView"
Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type controls:DataGridContainer}}, Path=CurrentView, Mode=OneWayToSource}" />
<Setter Property="CurrentColumnHeaderText"
Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type controls:DataGridContainer}}, Path=CurrentColumnHeader, Mode=OneWayToSource}" />
<Setter Property="SelectedCellText"
Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type controls:DataGridContainer}}, Path=SelectedText, Mode=OneWayToSource}" />
<Setter Property="IsDataGridFocused"
Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type controls:DataGridContainer}}, Path=HasFocus, Mode=OneWayToSource}" />
</Style>
And I have defined my control like this
<controls:CustomDataGrid x:Key="DataGridOne" AutoGenerateColumns="True" x:Shared="False" ItemsSource="{Binding UpdateSourceTrigger=PropertyChanged}" />
and the another one
<controls:DataGridContainer Content="{StaticResource DataGridOne}" DataContext="{Binding Products}"
x:Name="dataGridOne" SelectedItem="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type UserControl}},
Path=DataContext.SelectedItem, Mode=TwoWay}" CaptionVisibility="Collapsed"/>
Your style has x:Key attribute set. This means it won't apply to all controls of that type by-default. You should either remove the Key attribute to make the style default and apply to all CustomDataGrid controls, or reference Style in the CustomDataGrid definition like this:
<Window>
<Window.Resources>
<Style x:Key="CustomDataGridStyle" TargetType="{x:Type controls:CustomDataGrid}">
...
</Style>
</Window.Resources>
<controls:CustomDataGrid ... Style="{StaticResource CustomDataGridStyle}" ... />
</Window>

Categories