Remove an attribute from xaml using c# - WPF - wpf

This question is related to removing an attribute in xaml.
In the below code, I have a Span. During an event, I add a back ground to this Span. During another event, I need to remove it. Please let me know, if there is a way to remove the background attribute I set to Span.
My Xaml looks like this.
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication4"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition Height="40"></RowDefinition>
</Grid.RowDefinitions>
<RichTextBox x:Name="rtb">
<FlowDocument>
<Paragraph>
<Span x:Name="def" Tag="default">
<Run x:Name="deg">Some Text</Run>
</Span>
</Paragraph>
</FlowDocument>
</RichTextBox>
<TextBox x:Name="tx" Grid.Row="1" TextWrapping="Wrap"/>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Content="s" Click="Button_Click"/>
<Button Content="bg-Add" Grid.Column="1" Click="Button_Click"/>
<Button Content="bg-Remove" Grid.Column="2" Click="Button_Click"/>
</Grid>
</Grid>
</Window>
My code looks like this.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows. Shapes;
namespace WpfApplication4
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if ((sender as Button).Content.ToString() == "s")
{
tx.Text = XamlWriter.Save(def);
}
else if ((sender as Button).Content.ToString() == "bg-Add")
{
def.Background = new SolidColorBrush(Colors.Blue);
}
else if ((sender as Button).Content.ToString() == "bg-Remove")
{
//Need to remove the set back color so that I get the default back
}
}
}
}

I am able to find an answer myself.
def.ClearValue(Span.BackgroundProperty);
is going to remove that attribute for me.

You can override ShouldSerializeProperty
public class CustomizedSpan : Span
{
public bool IsRemoveBackGround;
protected override bool ShouldSerializeProperty(DependencyProperty dp)
{
if (dp == Span.BackgroundProperty && IsRemoveBackGround)
{
return false;
}
else
{
return base.ShouldSerializeProperty(dp);
}
}
}

Related

wpf usercontrol resizing with thumb not firing DragDelta

I have created a Usercontrol that I would like to make resizable using the thumb control. I have added my control to a Canvas and when I click on the thumb control the only events that are fired are Dragend and DragStart (in that order) and DragDelta is not even firing. I have found someone with a similar problem Thumb inside an ItemsControl not firing DragDelta event but there is no way I can ask them if they found a solution.
This is the code :
<UserControl x:Class="test.ucChair"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="53" d:DesignWidth="93" RenderTransformOrigin="0.5,0.5" Background="Beige"
>
<Grid Name="grd" Margin="0,0,0,0">
<Rectangle x:Name="rectAngle" Margin="0,0,0,0" Stroke="Black" RenderTransformOrigin="0.5,0.5" Grid.ZIndex="1000" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinHeight="53" /> <!-- Width="93" Height="53"-->
<TextBox x:Name="txtName" Text="OPEN" Margin="0,0,0,0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" IsReadOnly="True" IsReadOnlyCaretVisible="False" TextWrapping="Wrap" Width="93" KeyDown="txtName_KeyDown" FlowDirection="RightToLeft" BorderThickness="0" FontSize="14" Cursor="Hand" TextAlignment="Center"/>
<Thumb Name="thmbResize" DockPanel.Dock="Right" VerticalAlignment="Bottom" Height="15" Width="15"
DragDelta="OnResizeThumbDragDelta"
DragStarted="OnResizeThumbDragStarted"
DragCompleted="OnResizeThumbDragCompleted" HorizontalAlignment="Right">
</Thumb>
</Grid>
</UserControl>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace test
{
/// <summary>
/// Interaction logic for ucChairLeft.xaml
/// </summary>
public partial class ucChair : UserControl
{
public ChairType AngleType;
//?? public int SectionID;
public ucChair()//ChairType CType)//?, int _SectionID)
{
InitializeComponent();
}
private void OnResizeThumbDragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("DragEnd");
Mouse.Capture(null);
}
private void OnResizeThumbDragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
System.Diagnostics.Debug.WriteLine("DragDelta");
}
private void OnResizeThumbDragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
{
Mouse.Capture(this);
System.Diagnostics.Debug.WriteLine("DragStart");
}
}
}
<Window xmlns:test="clr-namespace:test" x:Class="test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="300" Width="300">
<Canvas Width="300" Height="300" Background="LightBlue">
<test:ucChair Canvas.Left="50" Canvas.Top="100" Width="50" Height="50" Background="Yellow"/>
</Canvas>
</Window>
Any help greatly appreciated!

WPF tile search in list view

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:EPOS.Desktop.UserControls"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls" xmlns:dxnav="http://schemas.devexpress.com/winfx/2008/xaml/navigation"
x:Class="EPOS.Desktop.UserControls.QeueOrders" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="600"
xmlns:tiles="clr-namespace:EPOS.Desktop.ViewModel">
<UserControl.DataContext>
<tiles:DemoViewModel x:Name="xyz"/>
</UserControl.DataContext>
<UserControl.Resources>
<StackPanel x:Key="tileTemplate">
<ListView>
<ListView.ItemTemplate>
<dxlc:Tile Content="{Binding Name}"/>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</UserControl.Resources>
<Grid>
<dxlc:TileLayoutControl ItemsSource="{Binding demos}" ItemTemplate="{StaticResource tileTemplate}" Grid.RowSpan="2"
Margin="21,0,-21,0"/> <!-- <dxlc:Tile Header="{Binding Name}" Click="Tile_Click" /> -->
<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="144,10,0,0" TextWrapping="Wrap" Text="TextBox"
VerticalAlignment="Top" Width="120"/>
</Grid>
</UserControl>
I want search tiles in WPF. So far I have found that it's possible only if I use listview. If you know any other best possible way, please share the solution.
this is xml:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:EPOS.Desktop.UserControls"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol" xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls" xmlns:dxnav="http://schemas.devexpress.com/winfx/2008/xaml/navigation" x:Class="EPOS.Desktop.UserControls.QeueOrders"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="600"
xmlns:tiles="clr-namespace:EPOS.Desktop.ViewModel"
>
<UserControl.DataContext>
<tiles:DemoViewModel x:Name="xyz"/>
</UserControl.DataContext>
<Grid>
<!--<dxlc:TileLayoutControl ItemsSource="{Binding demos}" ItemTemplate="{StaticResource tileTemplate}" Grid.RowSpan="2" Margin="21,0,-21,0" />-->
<!-- <dxlc:Tile Header="{Binding Name}" Click="Tile_Click" /> -->
<dxlc:TileLayoutControl Name="tileLayoutControl" ItemsSource="{Binding demos}" >
<dxlc:TileLayoutControl.ItemTemplate>
<DataTemplate>
<dxlc:Tile Header="{Binding Name}" Content="{Binding Name}"/>
</DataTemplate>
</dxlc:TileLayoutControl.ItemTemplate>
</dxlc:TileLayoutControl>
<Grid>
<dxe:SearchControl Name="search" Height="30" Width="200" Margin="38,0,362,270"/>
</Grid>
</Grid>
</UserControl>
This is with code-behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using EPOS.Desktop.ViewModel;
using EPOS.Desktop.View;
using EPOS.Desktop.Model;
using System.ComponentModel;
using DevExpress.Xpf.Editors;
using DevExpress.Xpf.LayoutControl;
namespace EPOS.Desktop.UserControls
{
/// <summary>
/// Interaction logic for QeueOrders.xaml
/// </summary>
public partial class QeueOrders : UserControl
{
public QeueOrders()
{
InitializeComponent();
DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(SearchControl.SearchTextProperty, typeof(SearchControl));
if (dpd != null)
{
dpd.AddValueChanged(search, OnSearchTextChanged);
}
}
private void OnSearchTextChanged(object sender, EventArgs e)
{
SearchControl tb = sender as SearchControl;
foreach (Tile t in tileLayoutControl.GetLogicalChildren(false))
{
if ((String.IsNullOrEmpty(tb.SearchText)) || (t.Content != null && t.Content.ToString().Contains(tb.SearchText)))
t.Visibility = Visibility.Visible;
else
t.Visibility = Visibility.Collapsed;
}
}
DemoViewModel demovm = new DemoViewModel();
private void Tile_Click(object sender, EventArgs e)
{
CategoryForm catform = new CategoryForm();
catform.ShowDialog();
}
}
}
But i want to do using MVVM patttern.

WPF: Dynamic views based on button clicks

I am a newbie to WPF and while I have read lots of theory and articles, I am unable to put it all together in a working solution.
Presently, I wish to implement dynamic multiple views in a window which could be selected by the user using buttons. The target is very much like one given in the question,
WPF : dynamic view/content
Can somebody please share with me a working code, of simplest implementation of the above. Just a window which contains two grids - one grid has two buttons - second grid changes background color depending on which button is clicked. From there on , I can take things further.
Thank you very much.
Use MVVM
It's a design approach. Basically you treat your Window as shell, and it's responsible for swapping views.
To simplify this snippet, I've referenced MvvmLight .
The Window contains ContentControl which dynamically displays the relevant view
Each dynamic view can communicate with the shell Window (using MvvmLight's Messenger) and tell it to change the view to something else.
MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainWindowViewModel></local:MainWindowViewModel>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Grid.Column="0" Command="{Binding ChangeFirstViewCommand}">Change View #1</Button>
<Button Grid.Row="0" Grid.Column="1" Command="{Binding ChangeSecondViewCommand}">Change View #2</Button>
<ContentControl Grid.Row="1" Grid.ColumnSpan="2" Content="{Binding ContentControlView}"></ContentControl>
</Grid>
</Window>
MainWindowViewModel.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
namespace WpfApplication1
{
public class MainWindowViewModel : ViewModelBase
{
private FrameworkElement _contentControlView;
public FrameworkElement ContentControlView
{
get { return _contentControlView; }
set
{
_contentControlView = value;
RaisePropertyChanged("ContentControlView");
}
}
public MainWindowViewModel()
{
Messenger.Default.Register<SwitchViewMessage>(this, (switchViewMessage) =>
{
SwitchView(switchViewMessage.ViewName);
});
}
public ICommand ChangeFirstViewCommand
{
get
{
return new RelayCommand(() =>
{
SwitchView("FirstView");
});
}
}
public ICommand ChangeSecondViewCommand
{
get
{
return new RelayCommand(() =>
{
SwitchView("SecondView");
});
}
}
public void SwitchView(string viewName)
{
switch (viewName)
{
case "FirstView":
ContentControlView = new FirstView();
ContentControlView.DataContext = new FirstViewModel() { Text = "This is the first View" };
break;
default:
ContentControlView = new SecondView();
ContentControlView.DataContext = new SecondViewModel() { Text = "This is the second View" };
break;
}
}
}
}
FirstView.xaml
<UserControl x:Class="WpfApplication1.FirstView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel>
<Label>This is the second view</Label>
<Label Content="{Binding Text}" />
<Button Command="{Binding ChangeToSecondViewCommand}">Change to Second View</Button>
</StackPanel>
</UserControl>
FirstViewModel.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace WpfApplication1
{
public class FirstViewModel : ViewModelBase
{
private string _text;
public string Text
{
get { return _text; }
set
{
_text = value;
RaisePropertyChanged("Text");
}
}
public ICommand ChangeToSecondViewCommand
{
get
{
return new RelayCommand(() =>
{
Messenger.Default.Send<SwitchViewMessage>(new SwitchViewMessage { ViewName = "SecondView" });
});
}
}
}
}
SecondView.xaml
<UserControl x:Class="WpfApplication1.SecondView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel>
<Label>This is the second view</Label>
<Label Content="{Binding Text}" />
<Button Command="{Binding ChangeToFirstViewCommand}">Change to First View</Button>
</StackPanel>
</UserControl>
SecondViewModel.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace WpfApplication1
{
public class SecondViewModel : ViewModelBase
{
private string _text;
public string Text
{
get { return _text; }
set
{
_text = value;
RaisePropertyChanged("Text");
}
}
public ICommand ChangeToFirstViewCommand
{
get
{
return new RelayCommand(() =>
{
Messenger.Default.Send<SwitchViewMessage>(new SwitchViewMessage { ViewName = "FirstView" });
});
}
}
}
}
SwitchViewMessage.cs
namespace WpfApplication1
{
public class SwitchViewMessage
{
public string ViewName { get; set; }
}
}

Wpf TabControl Interaction.Trigger fires mores than once

I have an unexpected behaviour with a Wpf-Tabcontrol and Dataemplate with Interaction.Trgiggers.
First I define a "ViewModel". It's quite simple:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
namespace WpfApplication3 {
public class Vm: INotifyPropertyChanged {
public Vm() {
this.CmdClick = new RelayCommand( p => this.ExecuteClick(), p => this.CanExecuteClick() );
}
private string myName;
public string MyName {
get { return myName; }
set {
if( myName != value ) {
myName = value;
if( this.PropertyChanged != null ) {
this.PropertyChanged( this, new PropertyChangedEventArgs( "MyName" ) );
}
}
}
}
private RelayCommand cmdClick;
public RelayCommand CmdClick {
get { return cmdClick; }
set { cmdClick = value; }
}
#region Command
private bool CanExecuteClick() {
return true;
}
public void ExecuteClick() {
MessageBox.Show( "MyName is " + MyName );
}
#endregion
public event PropertyChangedEventHandler PropertyChanged;
}
}
Next, I define a Datatemplate:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:l="clr-namespace:WpfApplication3"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DataTemplate DataType="{x:Type l:Vm}" x:Key="Vm">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox Text="{Binding Path=MyName}" Grid.Row="0"/>
<i:Interaction.Triggers>
<ei:KeyTrigger Key="F5" ActiveOnFocus="True" FiredOn="KeyUp" >
<i:InvokeCommandAction Command="{Binding CmdClick}" />
</ei:KeyTrigger>
</i:Interaction.Triggers>
</Grid>
</DataTemplate>
</ResourceDictionary>
I use the datatemplate on the mainform inside a TabControl:
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:WpfApplication3"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<TabControl>
<TabItem Header="Tab1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ContentControl ContentTemplate="{StaticResource Vm}" x:Name="vm11" Content="{Binding}" Grid.Row="0"/>
</Grid>
</TabItem>
<TabItem Header="Tab2">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ContentControl ContentTemplate="{StaticResource Vm}" x:Name="vm21" Content="{Binding}" Grid.Row="0"/>
<ContentControl ContentTemplate="{StaticResource Vm}" x:Name="vm22" Content="{Binding}" Grid.Row="1"/>
</Grid>
</TabItem>
</TabControl>
</Window>
The code behind is simple:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication3 {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
this.vm11.Content = vm1;
this.vm21.Content = vm2;
this.vm22.Content = vm3;
this.vm1.MyName = "Name1";
this.vm2.MyName = "Name2";
this.vm3.MyName = "Name3";
}
Vm vm1 = new Vm();
Vm vm2 = new Vm();
Vm vm3 = new Vm();
}
}
When i run the program, I chlick in the first TextBox, press F5 and the MessageBox posup. Ok.
I switch the tabpage, click inside the second TextBox, press F5 and the MessageBox appears again. OK.
I switch back to the firsz tabpage, press F5 and the MessageBox appears twice. Uuuh. Whatss wrong.
I switch back to the second tabpage,the messagebox appears twice again.
After switching to the first tabpage, the messagebox is displayed treetimes now. And so on.
It is like, the KeyUp-Event is assigned internaly, when the datatemplate is displayed again, without dereferencing it. But ehat can I do ?
I think you need to change this property from
private RelayCommand cmdClick;
public RelayCommand CmdClick {
get { return cmdClick; }
set { cmdClick = value; }
To
private RelayCommand cmdClick;
public RelayCommand CmdClick {
get { return cmdClick; }
set { if(cmdClick == null)cmdClick = value; }

How to make PanelDragDropTarget act only as a target and not as a source?

I created a new solution. I added a link to System.Windows.Controls.Toolkit to my Silverlight project and wrote this code:
XAML:
<UserControl x:Class="SilverlightApplication4.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<Grid>
<toolkit:PanelDragDropTarget Margin="0,0,150,150" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" AllowedSourceEffects="Copy">
<Grid Name="grid1" Background="Blue">
<Rectangle Height="40" HorizontalAlignment="Left" Margin="5,5,0,0" Name="rectangle1" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="80" Fill="Red" />
</Grid>
</toolkit:PanelDragDropTarget>
<toolkit:PanelDragDropTarget VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" Margin="150,150,0,0" AllowDrop="True" Drop="PanelDragDropTarget_Drop" AllowedSourceEffects="None">
<Grid Name="grid2" Background="Green" />
</toolkit:PanelDragDropTarget>
</Grid>
</Grid>
</UserControl>
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace SilverlightApplication4
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
private void PanelDragDropTarget_Drop(object sender, Microsoft.Windows.DragEventArgs e)
{
Rectangle myRectangle = new Rectangle() { Margin = new Thickness(5,5,0,0), Height = 40, Width = 80,
HorizontalAlignment = System.Windows.HorizontalAlignment.Left, VerticalAlignment = System.Windows.VerticalAlignment.Top,
StrokeThickness = 1, Stroke = new SolidColorBrush(Colors.Black), Fill = new SolidColorBrush(Colors.Red)};
grid2.Children.Add(myRectangle);
}
}
}
Now when I drag and drop the small red rectangle from grid1 onto grid2 everything works fine. But when I touch the new added rectangle in grid2 it shows visible signs that it can be dragged. My question is how to make a second PanelDragDropTarget (with grid2 inside) to act only as a target for drag and drop and not as a source? I mean how to block the possibility for a user to drag the new created rectangle in grid2, i.e. to exclude any visible signs that this new rectangle is draggable? Because it's not supposed to be draggable in my case.
I found a solution. For the PanelDragDropTarget adorner of the grid2 I defined an event handler for its ItemDragStarting event.
private void PanelDragDropTarget_ItemDragStarting(object sender, ItemDragEventArgs e)
{
e.Cancel = true;
e.Handled = true;
}
Now when I try to drag elements in grid2 nothing happens (that was my purpose).
Have you tried AllowedSourceEffects="None", works for me in SL5...

Resources