|
I guess the thing I would really want it to be able to detect when the user has clicked inside a custom drawn control.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
While my user controls may not have "click" events, they can respond to "preview mouse down" which "act" like click handlers or context menu popups (to the user).
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
Right, but how do you know if the user clicked inside the shape? If I had a user control, which is square or rectangular, and I draw a triangle or star on it, I would want to only handle the mouse down if it's actually inside the shape I've drawn.
I guess you could evaluate the current mouse position and see if it falls within the path, but that seems rather complex.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
My "shape" would be an "object", that you "shape"; not something I could "click through" in that case.
(If I didn't want to resort to "hit-point" calculations; and I don't).
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
Gerry Schmitz wrote: (If I didn't want to resort to "hit-point" calculations; and I don't).
My point exactly
So how do you create an object that has an irregular shape?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Here's an idea..
Create a Shape Designer app similar to Blend but MUCH more simple. The user can create basic shapes - Lines, Polygon, Rectangle, Ellipse, etc. This app then saves the path data to a meta-data file that my designer uses to load a toolbox.
Tn my resources I would have
<Style x:Key="BaseShapeStyle"
TargetType="Shape">
;Setter Property="Cursor" Value="Hand" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Stroke" Value="{Binding Stroke}" />
<Setter Property="StrokeThickness" Value="{Binding StrokeThickness}" />
<Setter Property="Fill" Value="{Binding Fill}" />
</Style>
<Style x:Key="EllipseStyle"
TargetType="{x:Type Ellipse}"
BasedOn="{StaticResource BaseShapeStyle}">
<Setter Property="Height" Value="{Binding Height}" />
<Setter Property="Width" Value="{Binding Width}" />
</Style>
Then in a user control I would have:
<Ellipse Style="{DynamicResource EllipseStyle}"
ToolTip="{Binding ElectrodeDisplayText}"
MouseLeftButtonDown="Ellipse_MouseLeftButtonDown"
MouseLeftButtonUp="Ellipse_MouseLeftButtonUp"
MouseMove="Ellipse_MouseMove"/>
So this way the basic shapes could all have their data saved and re-bound at runtime, and the UI pieces are very small.
By using the basic shapes and some grouping the user could create pretty much anything they wanted.
What do you think?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Yes; that's building up from "smaller" shapes. Still too "big" for me; and I have to build the "starter set".
As I said, use WPF Path commands.
It uses co-ordinates.
You click, you have a co-ordinate and a point.
You can now drag the point.
You draw a line back to the last point.
Etc.
Let the user do the work; all of it.
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
|
datagrid can have single selected item which I can bind to property in view model what should I do for having multiple selected items using view model (mvvm)
|
|
|
|
|
Make sure you have an IsSelected property in your row ViewModel. Then, in your DataGrid, add this:
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
</Style TargetType="DataGridRow">
</DataGrid.RowStyle>
This space for rent
|
|
|
|
|
Thank You For reply but I have tried it and bind this value to property in view model and added breakpoint to that but after selecting multiple items command didn't break at that point therefore multiple items didn't get there
|
|
|
|
|
I use Telerik but I am certain the same binding works for all grids
Xaml
<telerik:RadGridView x:Name="tkGrid" Grid.Row="2" ItemsSource="{Binding EntityList,Mode=TwoWay}" SelectedItem="{Binding SelectedEntity,Mode=TwoWay}" >
<telerik:RadGridView.Columns> etc...
in the VM I have an observable collection and a selected item
#region -------- Entity selected item<br />
private EntityDB _SelectedEntity;
public EntityDB SelectedEntity
{
get
{ return _SelectedEntity; }
set
{
if (_SelectedEntity == value)
{ return; }
var oldValue = _SelectedEntity;
_SelectedEntity = value;
base.RaisePropertyChanged("SelectedEntity");
}
}
#endregion -------- Entity
This works for single item selection. For multiple selected items I have to use code behind to get the SelectedItems collection of the grid and pass it to the VM
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Here's my XAML
<ComboBox Grid.Row="0"
Grid.Column="1"
ItemsSource="{Binding Clients}"
DisplayMemberPath="ClientName"
SelectedValuePath="Id"
SelectedValue="{Binding SelectedClientId}"
Margin="2"
Width="200"
HorizontalAlignment="Left"/>
The combo is bound to an ObservableColection<cliententity> called Clients, The collection is being loaded and the data is valid. No binding errors.
When I run it I don't see anything in the list.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Is the list populated but not displaying text - typo in the field name
SelectedValue should probably be binding to SelectedClient.ID and should be two way
If there is nothing in the combobox at all then it is probably a typo in the list name (I assume there is data in the viewmodel)
Also check that the datacontext connects to your viewmodel.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
All of this checks out OK. No typos, and there is data. The DataContext is connected
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Well I just figured it out...
The MainWindowView has
<DataTemplate DataType="{x:Type vms:MyViewModel}">
<vw:MyView/>
</DataTemplate>
The VM's are based off a subclass that has a Load method. In the MainWindowViewModel when a view is selected I create MyViewModel and call the Load, which does
private void LoadClientsList()
{
var clients = _dal.GetClients();
Clients = new ObservableCollection<ClientEntity>(clients);
}
This all worked fine.
I just found this in MyView:
<UserControl.DataContext>
<vms:BacklogViewModel/>
</UserControl.DataContext>
This second call was recreating the VM, so the Clients collection was reset to null;
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Kevin Marois wrote: <DataTemplate DataType="{x:Type vms:MyViewModel}"> Ah he thinks there may be a reason why I have not seen that construct before.
I have to admit I only ever instantiate a datacontext from the view.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
I have created a style for a listbox:
ItemContainerStyle
<Style x:Key="listBoxItemContainerStyle"
TargetType="ListBoxItem">
<pre>
<Setter Property="Padding" Value="2"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="Black"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Orange"/>
<Setter Property="Foreground" Value="Blue"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Orange"/>
<Setter Property="Foreground" Value="Blue"/>
</Trigger>
</Style.Triggers>
ListBoxStyle
<Style x:Key="listBoxStyle"
TargetType="ListBox">
<pre>
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Background" Value="White"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBackgroundBrush}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ItemContainerStyle" Value="{StaticResource listBoxItemContainerStyle}"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="BorderBrush" Value="{StaticResource ButtonDisabledBackgroundBrush}"/>
<Setter Property="Control.BorderThickness" Value="2"/>
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True"/>
</Trigger>
</Style.Triggers>
Usage
<ListBox Grid.Row="1"
Grid.Column="4"
Style="{StaticResource listBoxStyle}">
<pre>
<ListBoxItem Content="One" IsSelected="True"/>
<ListBoxItem Content="Two" IsEnabled="False"/>
<ListBoxItem Content="333333"/>
When I run it BEFORE I click an item, the background of the first item is lightgray. Notice that the first item has IsSeledted= true.
If I click on it, then the background color turns Blue.
What's wrong here?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Hello,
the problem is that the default control template for ListBoxItem contains a border element which controls the background color. To fully control the appearance you could replace the template using the template from ListBoxItem ControlTemplate Example[^] with your own definition. See below for an example.
<Style x:Key="listBoxItemContainerStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Name="Border" Padding="2" SnapsToDevicePixels="true">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Border" Property="Background" Value="Orange"/>
<Setter Property="Foreground" Value="Blue"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="Gray"/>
<Setter TargetName="Border" Property="BorderThickness" Value="2"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="Orange"/>
<Setter Property="Foreground" Value="Blue"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
|
|
|
|
|
I'm trying to create a simple Watermark TextBox. I first created a TextBox class with a WatermarkText property:
public class MaroisTextBox : TextBox
{
#region DP WatermarkText
public static readonly DependencyProperty WatermarkTextProperty =
DependencyProperty.Register("WatermarkText",
typeof(string),
typeof(MaroisTextBox),
new PropertyMetadata("", new PropertyChangedCallback(OnWatermarkTextChanged)));
public string WatermarkText
{
get { return (string)GetValue(WatermarkTextProperty); }
set { SetValue(WatermarkTextProperty, value); }
}
private static void OnWatermarkTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MaroisTextBox control = (MaroisTextBox)d;
control.SetWatermark();
}
#endregion
#region Overrides
protected override void OnGotFocus(RoutedEventArgs e)
{
base.OnGotFocus(e);
SetWatermark();
}
protected override void OnLostFocus(RoutedEventArgs e)
{
base.OnLostFocus(e);
SetWatermark();
}
#endregion
private void SetWatermark()
{
if (IsFocused)
{
if (Text.CompareTo(WatermarkText) == 0)
{
Text = string.Empty;
}
}
else
{
if (string.IsNullOrEmpty(Text))
{
Text = WatermarkText;
}
}
}
}
Next I created a style for it
<Style x:Key="SearchTextBoxStyle"
TargetType="TextBox">
<pre>
<Setter Property="FontFamily" Value="{StaticResource AppFontName}"/>
<Setter Property="FontSize" Value="{StaticResource NormalFontSize}"/>
<Setter Property="FontStyle" Value="Normal"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="Height" Value="30"/>
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="FontStyle" Value="Italic"/>
</Trigger>
</Style.Triggers>
And its usage
<MaroisTextBox Grid.Column="3"
Width="200"
Margin="20,2,2,2"
Text="{Binding SearchText}"
WatermarkText="Search..."
Style="{StaticResource SearchTextBoxStyle}"/>
When I click into the textbox, the code behind runs as expected. Yet I don't see anything in the textbox.
When I click out, the watermark text appears, but in black and not italic.
I don't see why this won't work. Anyone see what's wrong here?
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Kevin Marois wrote: When I click into the textbox, the code behind runs as expected. Yet I don't see anything in the textbox.
Which is what you told it to do:
Kevin Marois wrote:
if (IsFocused)
{
if (Text.CompareTo(WatermarkText) == 0)
{
Text = string.Empty;
}
}
Kevin Marois wrote: When I click out, the watermark text appears, but in black and not italic.
Which is also what you told it to do:
Kevin Marois wrote:
<Setter Property="FontStyle" Value="Normal"/>
<Setter Property="Foreground" Value="Black"/>
...
<Trigger Property="IsFocused" Value="True">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="FontStyle" Value="Italic"/>
</Trigger>
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I meant to say "When I click OUT of it"
On startup the DP is being set to the watermark, yet nothing appears in the TextBox
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
It's probably being overridden by the binding.
Changing the Text property to create a watermark isn't really a good idea. Try one of the other solutions from this SO thread[^], or this GitHub project[^].
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I already saw the SO one. Not really a god idea either. It contains two textboxes and just hides either one.
The GitHub solution seems right.
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I have a DataGrid bound to an ObservableCollection<myclass>. MyClass has a Name property on it. The model implements INotifyPropertyChanged.
When in the grid the user changes a Name value on any row the selected row'a Name property on the model is updated.
How can I know in ViewModel that a model bound to a data grid has changed?
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|