I'm using GraphX for .NET and I'm trying to highlight a vertex when the user clicks on it.
I registered for the VertexSelected event:
public class MyGraphArea : GraphArea<Node, Edge, MiniFlowGraph>
{
public MyGraphArea()
{
VertexSelected += VertexSelected_MarkVertex;
}
private void VertexSelected_MarkVertex(object sender,VertexSelectedEventArgs args)
{
HighlightBehaviour.SetHighlighted(args.VertexControl, true);
}
}
But nothing happened in the UI. So I tried to add multiple options:
To the constructor I added:
EnableVisualPropsApply = true;
HighlightBehaviour.SetIsHighlightEnabled(this, true);
SetVerticesHighlight(true, GraphControlType.VertexAndEdge);
I also registered to the Loaded event and added this code:
foreach (var item in VertexList)
HighlightBehaviour.SetIsHighlightEnabled(item.Value, true);
Then I added the line SetVerticesHighlight(true, GraphControlType.VertexAndEdge) to the VertexSelected event, just for case.
But nothing happened.
I'm looking at the source code, and I can't find anything else.
I believe you just need to add the following lines of code:
Graph.SetEdgesHighlight(true, GraphControlType.VertexAndEdge);
Graph.SetVerticesHighlight(true, GraphControlType.VertexAndEdge, EdgesType.All);
I was playing around with the WindowsFormsProject example, and I added these lines just before the return statement of the method Form1.GenerateWpfVisuals(). I did not had to subscribe to any event. However, the standard behavior will highlight vertices and edges on mouse hover, not on mouse click.
The default Gold color is used for the highlighting is defined in template.xaml:
<!-- VERTEX CONTROL -->
...
<Style.Triggers>
<Trigger Property="controls:HighlightBehaviour.Highlighted" Value="True">
<Setter Property="Background" Value="Gold"/>
<Setter Property="BorderThickness" Value="7"/>
</Trigger>
</Style.Triggers>
...
<!-- EDGE CONTROL -->
...
<Style.Triggers>
<Trigger Property="controls:HighlightBehaviour.Highlighted" Value="True">
<Setter Property="Foreground" Value="Gold"/>
<Setter Property="StrokeThickness" Value="5"/>
</Trigger>
</Style.Triggers>
Related
I had a Picture Box in Windows Forms using as a button named pbSignin. I managed to change the background of this picture box on mouse hover and also put the function of signin under this picture box.
Now I want the same to happen in WPF Application, but it gives error in WPF, I have no idea what to do.... Please Help
pbSignin.MouseEnter += new EventHandler(pbSignin_MouseEnter);
pbSignin.MouseLeave += new EventHandler(pbSignin_MouseLeave);
private void pbSignin_MouseLeave(object sender, EventArgs e)
{
this.pbSignin.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.RedSignin));
}
private void pbSignin_MouseEnter(object sender, EventArgs e)
{
this.pbSignin.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.BlueSignin));
}
Here is an example of how to change the background color of a button on mouse over. Just apply to the style to your control, change the TargetType and Setter properties for your picturebox and you should be good to go.
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
The first Setter, outside the trigger, is the default value for the property. When the trigger condition fires it will overwrite the default value and revert it once the trigger is no longer firing.
I have a strange problem, I'm currently trying to styling a SingleUpDown Control (from Extended WPF Toolkit)
This is the current style that does not work:
<xctk:SingleUpDown>
<xctk:SingleUpDown.Style>
<Style TargetType="xctk:SingleUpDown">
<Style.Triggers>
<DataTrigger Binding="{Binding _ThresoldLocked}" Value="True">
<Setter Property="Value" Value="2"/>
</DataTrigger>
</Style.Triggers>
</Style>
</xctk:SingleUpDown.Style>
</xctk:SingleUpDown>
While these two examples work like a charm:
<xctk:SingleUpDown>
<xctk:SingleUpDown.Style>
<Style TargetType="xctk:SingleUpDown">
<Style.Triggers>
<DataTrigger Binding="{Binding _ThresoldLocked}" Value="True">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</xctk:SingleUpDown.Style>
</xctk:SingleUpDown>
Or
<xctk:SingleUpDown>
<xctk:SingleUpDown.Style>
<Style TargetType="xctk:SingleUpDown">
<Setter Property="Value" Value="2"/>
</Style>
</xctk:SingleUpDown.Style>
</xctk:SingleUpDown>
What I'm doing wrong with the first Style?
There's no Error in the Output window..
EDIT:
This is my minimalist example:
http://i.stack.imgur.com/EzxBP.png
Usually when it comes to styles and triggers people are not aware of precedence, namely that local values among others completely override styles. Given the fact that you did not set any properties on the controls all styles should work.
So for example if you set the Value on your control (<xctk:SingleUpDown Value="0">...) the trigger does nothing, you would then move defaults into a Setter.
<xctk:SingleUpDown>
<xctk:SingleUpDown.Style>
<Style TargetType="xctk:SingleUpDown">
<Setter Property="Value" Value="<default here>"/>
<Style.Triggers>
<DataTrigger Binding="{Binding _ThresoldLocked}" Value="True">
<Setter Property="Value" Value="2"/>
</DataTrigger>
</Style.Triggers>
</Style>
</xctk:SingleUpDown.Style>
</xctk:SingleUpDown>
Edit:
I made an observation about the control's behaviour. If you have a setup as shown above the Trigger will work, so the default setter is kind of necessary here.
Also you should note that manipulating the value will probably set it locally, thus overriding any further effects from the trigger. You can get around this by using animations instead of triggers as they have the highest precedence, however this may then void any manual manipulation.
Maybe you should move your logic away from the UI and just bind the Value directly to a property on your view-model/model, e.g.
private bool _ThresholdLocked;
public bool ThresholdLocked
{
get { return _ThresholdLocked; }
set
{
if (value != _ThresholdLocked)
{
_ThresholdLocked= value;
OnPropertyChanged("ThresholdLocked");
OnPropertyChanged("Value"); //Value is also affected
}
}
}
private float _Value;
public float Value
{
get
{
if (ThresholdLocked)
return 2.0f;
return _Value;
}
set
{
if (value != _Value)
{
_Value = value;
OnPropertyChanged("Value");
}
}
}
I using Extended WPF Toolkit, but I don't have SingleUpDown there, but you probably talking about different version than this is: http://wpftoolkit.codeplex.com/. I have there DoubleUpDown and your nonfunctional style works for me.
I have a style with a Trigger for IsMouseOver, and I want to trigger that Trigger (heh) from C#. How can this be done? Thanks in advance!
You can create a DataTrigger and then bind to a property in your ViewModel.
First create a bool property that will advise the View whether it should 'show' or 'not show' your style.
public bool GridTrigger
{
get { return this.gridTrigger; }
set { // raise a PropertyChange event, as per normal
}
And then add the DataTrigger to the XAML
<Grid.Triggers>
<DataTrigger Binding="{Binding GridTrigger}" Value="True">
<Setter Property="Style" Value="{StaticResource MyMouseOverStyle"/>
</DataTrigger>
</Grid.Triggers>
This obviously assumes you are using MVVM!
I am fairly new to WPF but have spent time researching WPF validation, and have not yet seen a good approach to conditional validation.
To simplify the situation greatly, let's say I have two textboxes and a submit button. The user enters a string in the first textbox. If the user enters, for example "ABC", then the second textbox should be a required field (I'd want the background to be a light blue color, to signify this), and the submit button should be disabled until that textbox is populated.
How can this be done? Is there an easy way to add/remove validations in runtime? 'DataAnnotations' (http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx) seemed like a good starting place, however I can't mark a field with the [Required] attribute, as the field won't always be required. Basically, I need something like 'Required if Field1 = 'ABC'
Thanks!
I would handle it using MVVM and here is a sample for that.
Implement IDataError Info on the class and that will implement two properties Error and this[string columnName] you can implement the second property with your binding errors that you want
public class MainViewModel:ViewModelBase,IDataErrorInfo
{
public string Error
{
}
public string this[string columnName]
{
get
{
string msg=nulll;
switch(columnName)
{
case "MyProperty": //that will be your binding property
//choose your validation logic
if(MyProperty==0||MyProperty==null)
msg="My Property is required";
break;
}
return msg;
}
}
Also Set ValidateOnErrors=True in binding of a textbox. here ColumnName is the name of the property that is changed and that has ValidateOnErrors set to true. Check here and put up the conditions and return message then you will see the errors on the tooltip when you put this style in your Resources.
<UserControl.Resources>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true" >
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Background" Value="MistyRose"/>
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="1.0"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self},Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
and here is a sample of the textbox
<TextBox Text="{Binding UpdateSourceTrigger=PropertyChanged, Mode=TwoWay,
Path=PropertyName,ValidatesOnDataErrors=True}" Name="textBox1">
<Validation.ErrorTemplate>
<ControlTemplate>
</ControlTemplate>
</Validation.ErrorTemplate>
</TextBox>
I would just handle this logic in your ViewModel (assuming you're using an MVVM pattern, if not just in your code-behind).
Fire some logic on the TextChanged event for the first textbox that ultimately sets the appropriate properties. Essentially I'm saying code this validation manually. Once you start getting into more complex validation logic like this your going to start running into the limitations of the validation frameworks / declarative validation.
I want to derive from System.Windows.Controls.TextBox and provide this functionality.
IsEnabledProperty.OverrideMetadata(typeof(MyTextBox), new FrameworkPropertyMetadata(
new PropertyChangedCallback(delegate(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
MyTextBox tb = o as MyTextBox;
if (tb != null && !tb.IsEnabled)
{
tb.SetValue(TextProperty, null);
tb.OnLostFocus(new RoutedEventArgs(LostFocusEvent, typeof(MyTextBox)));
}
}
)));
The problem is that if I write a Custom Control, nothing will be displayed when using it, but I don't want to write my custom Template. I want to use the original one.
How would you do that, please ?
Check and see if your control overrides the DefaultStyleKeyProperty
DefaultStyleKeyProperty.OverrideMetadata
If that is the case, it will expect to find a style somewhere. Remove that override and you should be seeing normal TextBox behaviour!
If it does not, you can always base your new Textbox style on your old style, like so:
<Style TargetType="{x:Type Your:YourTextBox}" BasedOn="{StaticResource {x:Type TextBox}}" />
Place it in a ResourceDictionary somewhere, and it should work as well!
Hope this helps!
There is a much simpler option, here. Just use a DataTrigger to set your TextBox's Text to null (or empty) when the TextBox.IsEnabled is false:
<Style TargetType="TextBox">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsEnabled}" Value="False">
<Setter Property="Text" Value="" />
</DataTrigger>
</Style.Triggers>
</Style>