Create a simple wpf trigger on one object that affects another
TargetName is not intended for use within the Triggers collection of a Style. A style does not have a namescope, so it does not make sense to refer to elements by name there. But a template (either DataTemplate or ControlTemplate) does have a namescope.
See this link.
You can do it the other way around with a DataTrigger for the Button. Note that you must set the Property Visibility within the Style for the DataTrigger to work.
<Grid Name="MainGrid">
<DataGrid ItemsSource="{Binding Programs}"
IsReadOnly="True"
AutoGenerateColumns="false" >
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
<DataGridTextColumn Header="Version" Binding="{Binding Version}"/>
<DataGridTextColumn Header="Publisher" Binding="{Binding Publisher}"/>
</DataGrid.Columns>
</DataGrid>
<Button Name="ButtonExpand"
Height="25"
Width="25"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Content="+">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=MainGrid,
Path=IsMouseOver}"
Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
Another way to do it would be to bind Visibilty of ButtonExpand to the IsMouseOver property of the DataGrid with a converter.