Hi i'm creating an checklistbox
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox x:Name="CheckBox" Content="{Binding Path=Info.Name}" IsChecked="{Binding IsChecked,Mode=TwoWay}" Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MainViewModel}}, Path=SimpleCommand}">
</CheckBox>
<TextBlock Margin="20,0,0,0" Text="{Binding Path=Status}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
but when i check the simplecommand isn't call
SimpleCommand = new RelayCommand(obj => MessageBox.Show("alert"), obj => true);
Use the control name rather than the viewmodel for ancestor type
<CheckBox x:Name="CheckBox"
Content="{Binding Path=Info.Name}"
IsChecked="{Binding IsChecked,Mode=TwoWay}"
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=SimpleCommand}"/>
Related
I want to trigger a command when I use a MiddleClick on a Checkbox in an ItemsControl. I need to return the item source as a command parameter. I have tried two methods in XAML.
Method 1:
<ItemsControl x:Name="CheckBoxItems" ItemsSource="{Binding Curves}" Grid.Row="1">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked}" Margin="0,0,5,0"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.InputBindings>
<MouseBinding Gesture="MiddleClick" Command="{Binding SelectOnlyCommand}"
CommandParameter="{Binding }"/>
</ItemsControl.InputBindings>
</ItemsControl>
This method returns the UserControl to the command instead of the item source.
Method 2:
<ItemsControl x:Name="CheckBoxItems" ItemsSource="{Binding Curves}" Grid.Row="1">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked}" Margin="0,0,5,0">
<CheckBox.InputBindings>
<MouseBinding Gesture="MiddleClick" Command="{Binding Path=SelectOnlyCommand}"
CommandParameter="{Binding }"/>
</CheckBox.InputBindings>
</CheckBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
This method does not trigger the SelectOnlyCommand. Thanks for your help.
(Edited)
if you want to pass the single item, it works like this:
<ItemsControl x:Name="CheckBoxItems" ItemsSource="{Binding Curves}" Grid.Row="1">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked}" Margin="0,0,5,0">
<CheckBox.InputBindings>
<MouseBinding Gesture="MiddleClick" Command="{Binding ElementName=CheckBoxItems, Path=DataContext.SelectOnlyCommand}"
CommandParameter="{Binding }"/>
</CheckBox.InputBindings>
</CheckBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
You can achieve that with way 2 , but problem is you not able to bind Command. You will have to bind it by ElementName.
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked}" Margin="0,0,5,0">
<CheckBox.InputBindings>
<MouseBinding Gesture="MiddleClick" Command="{Binding ElementName=CheckBoxItems, Path = DataContext.SelectOnlyCommand}"
CommandParameter="{Binding }"/>
</CheckBox.InputBindings>
</CheckBox>
My Application consists of a MainWindow with a ContentControl and I change the ViewModel depending on the selected menu.
One of the UserControls I display as content contains the following WrapPanel:
<UserControl ...>
<Grid>
<WrapPanel>
<ItemsControl ItemsSource="{Binding Connections}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Command="{Binding DataContext.ConnectionSelectCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
CommandParameter="{Binding}"
FocusManager.FocusedElement="{Binding ElementName=InstanceName}"
Style="{DynamicResource DashboardButton}">
<TextBlock TextWrapping="Wrap" HorizontalAlignment="Center" Text="{Binding Name}" />
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="Delete"
Command="{Binding ConnectionRemoveCommand}"
CommandParameter="{Binding}" />
</ContextMenu>
</Button.ContextMenu>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</WrapPanel>
</Grid>
</UserControl>
The Command on the ContextMenu doesn't work because it tries to call ConnectionRemoveCommand on the Connection object instead of the ConnectionViewModel which is the DataContext of the UserControl.
How do I bind the Command to the ConnectionViewModel with the CommandParameter being the Connection object?
If you bind the Tag property of the Button to the DataContext of the ItemsControl, you could then bind to it using the PlacementTarget of the ContextMenu:
<Button Command="{Binding DataContext.ConnectionSelectCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
CommandParameter="{Binding}"
FocusManager.FocusedElement="{Binding ElementName=InstanceName}"
Style="{DynamicResource DashboardButton}"
Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType=ItemsControl}}">
<TextBlock TextWrapping="Wrap" HorizontalAlignment="Center" Text="{Binding Name}" />
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="Delete"
Command="{Binding PlacementTarget.Tag.ConnectionRemoveCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
CommandParameter="{Binding}" />
</ContextMenu>
</Button.ContextMenu>
</Button>
I am trying to bind the background color of a TextBox and use a converter. However, I can't figure out the correct binding due to the TextBox being in a DataTemplate and in a ContentControl.
The DebuggingConverter doesn't fire unless I set the binding path from Path=StateColor to Path=.
Here is the xaml :
<GridViewColumn Header="Value" Width="{Binding SelectedDeviceCol2, Source={x:Static properties:Settings.Default}, Mode=TwoWay}" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<ContentControl Content="{Binding Path=Value, Mode=TwoWay}" IsEnabled="{Binding Path=ReadOnly, Converter={StaticResource readOnlyToEnabledConverter}}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type viewModels:VMDeviceCommand}">
<Button Content="{Binding Name}" Height="24" IsEnabled="True" Click="Button_Click_GetObjectProperty"/>
</DataTemplate>
<DataTemplate DataType="{x:Type System:DateTime}">
<DatePicker SelectedDate="{Binding Path=.}"
SelectedDateFormat="Short"
FirstDayOfWeek="Monday"
IsTodayHighlighted="True" >
</DatePicker>
</DataTemplate>
<DataTemplate DataType="{x:Type System:String}">
<TextBox Text="{Binding Path=.}" TextChanged="TextBox_OnTextChanged">
<TextBox.Background>
<SolidColorBrush Color="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=StateColor, Converter={StaticResource DebuggingConverter}}"/>
</TextBox.Background>
</TextBox>
</DataTemplate>
<DataTemplate DataType="{x:Type System:UInt16}">
<xctk:IntegerUpDown Text="{Binding Path=.}" ValueChanged="UpDownBase_OnValueChanged" >
</xctk:IntegerUpDown>
</DataTemplate>
<DataTemplate DataType="{x:Type System:Boolean}">
<CheckBox IsChecked="{Binding Path=.}" Click="CheckBox_Click"/>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</DataTemplate>
</GridViewColumn.CellTemplate>
ContentControl doesn't have a StateColor property, so the Binding never gets its value and never has anything to pass to a converter.
If the ContentControl's DataContext has a StateColor property, that's easy:
<SolidColorBrush
Color="{Binding DataContext.StateColor, RelativeSource={RelativeSource AncestorType=ContentControl}, Converter={StaticResource DebuggingConverter}}"
/>
I try to bind the IsEnabled Property of a Checkbox to IsChecked of another Checkbox in a Listview. What is wrong?
<TreeView ItemsSource="{Binding Rulesets}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Rules}">
<StackPanel Orientation="Horizontal">
<CheckBox Name="rulesetCheckbox" IsChecked="{Binding IsActivated}"></CheckBox>
<TextBlock Text="{Binding Name}" />
</StackPanel>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsEnabled="{Binding ElementName=rulesetCheckbox, Path=IsChecked}" IsChecked="{Binding IsActivated}"></CheckBox>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Thanks!
Consider the following XAML
<ItemsControl ItemsSource="{Binding Path=MyItems, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" AlternationCount="999" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=(ItemsControl.AlternationIndex),
RelativeSource={RelativeSource TemplatedParent},
FallbackValue=FAIL,
StringFormat={}Index is {0}}" />
<ItemsControl ItemsSource="{Binding Path=MySubItems, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}, AncestorLevel=1}, Path=(ItemsControl.AlternationIndex)}"/>
<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}, AncestorLevel=2}, Path=(ItemsControl.AlternationIndex)}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
There are three TextBlock nodes. The 1st TextBlock is a direct child of the 1st ItemsControl, and shows the AlternationIndex, as expected. However, I need that AlternationIndex a level deeper, in the second ItemsControl. Therefore I can't use TemplatedParent and thought I could find the Ancestor with AncestorLevel. However, both TextBlock nodes in the 2nd ItemsControl show "0".
What I'm I missing? How do I target the 1st ItemsControl from within the 2nd ItemsControl?
The AlternationIndex won't be on the ItemsControl but on each of its children. Using DataTemplate your ItemsControl will store each children in a ContentPresenter which will have the AlternationIndex. What you need to modify:
<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentPresenter}, AncestorLevel=2}, Path=(ItemsControl.AlternationIndex)}"/>
<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentPresenter}, AncestorLevel=2}, Path=(ItemsControl.AlternationIndex)}"/>