|
It's fairly straightforward to do. Hook up to the CollectionChanged event handler from your ObservableCollection and then, whenever the collection changes, you add or remove event handlers. The event handling looks a bit like this:
private void HandleCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.OldItems != null)
{
foreach (object item in e.OldItems)
{
((INotifyPropertyChanged)item).PropertyChanged -= MyPropertyChangedHandler;
}
}
if (e.NewItems != null)
{
foreach (object item in e.NewItems)
{
((INotifyPropertyChanged)item).PropertyChanged += MyPropertyChangedHandler;
}
}
} This means, whenever you add or remove an item to your collection, you now have the ability to hook into the models INPC chain. This might look a bit like this:
private void MyPropertyChangedHandler(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName != "Name") return;
MyModel model = sender as MyModel;
Debug.WriteLine($"Name changed to {model.Name}");
}
This space for rent
|
|
|
|
|
Ouch - I do that for a single item on the selectedobject property change, never considered it for an entire collection.
I almost never allow inline editing of grid data, the odd checkbox or single cell is handle by the celleditend event.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
I have to admit, I've never been the biggest fan of inline editing. I generally prefer to look at other methods of editing grid data, such as through the use of dialog boxes. Saying that, the approach I outlined here is simple enough to do (although I tend to use RX to watch collection and property changes).
This space for rent
|
|
|
|
|
Hi Guys, I have created a WPF Application which needs to run forever, so, I want to disable closing of application from task manager. I applied some code, and in apps section in task manager, I am able to disable closing of application, but when I close it from background processes in task manager then close it from apps section, it does not get restarted and get closed.
So, Is there any way by which I can restart my application once it gets closed from background processes in Task Manager or any other method to do this operation. Any help would be greatly appreciated. Please suggest.
|
|
|
|
|
About the only thing you could realistically do is have a service running that monitors the status of the application and then fires it off if it's been killed off. The service would have to periodically poll the application to determine whether or not the app was running (it would also have to take into account whether the app was closed because the computer was shutting down).
This space for rent
|
|
|
|
|
I have created a RadioButton who's style will look similar to this. In my version the line can be top, left, right, or bottom.
In the code behind I did:
public class MaroisRadioButton : RadioButton
{
public enum Position
{
Bottom,
Left,
Right,
Top
}
#region DP RadioMarkPosition
public static readonly DependencyProperty RadioMarkPositionProperty =
DependencyProperty.Register("RadioMarkPosition",
typeof(Position),
typeof(MaroisRadioButton),
new PropertyMetadata(Position.Left));
public Position RadioMarkPosition
{
get { return (Position)GetValue(RadioMarkPositionProperty); }
set { SetValue(RadioMarkPositionProperty, value); }
}
#endregion
#region DP RadioMarkSize
public static readonly DependencyProperty RadioMarkSizeProperty =
DependencyProperty.Register("RadioMarkSize",
typeof(double),
typeof(MaroisRadioButton),
new PropertyMetadata(null));
public double RadioMarkSize
{
get { return (double)GetValue(RadioMarkSizeProperty); }
set { SetValue(RadioMarkSizeProperty, value); }
}
#endregion
}
Then I created style for it and in the style I want to bind the RadioMarkSize to the Width property in the XAML:
<Border Grid.Row="1"
Grid.Column="0"
Margin="2"
Background="{DynamicResource buttonPressedBackBrush}"
Width="{Binding RadioMarkSize}"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
Name="LeftRadioMark"/>
But I can't get the binding to work. I get a binding error "BindingExpression path error: 'RadioMarkSize' property not found on 'object' ''MainWindowViewModel'"
How do I bind the Width property to the DP in the code behind?
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
The DependencyProperty is on a derived RadioButton and you're attempting to read it on a Border bound to the VM DataContext. That's why your code can't see it. Why not put your derived RadioButton on there and get access to the DPs from that?
|
|
|
|
|
Here's the full style. The Border is part of the RadioButton Control Template's BulletDecarator:
<Style x:Key="BlockRadioButtonStyle"
TargetType="{x:Type mbc:MaroisRadioButton}"
BasedOn="{StaticResource BaseRadioButtonStyle}">
<pre>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type mbc:MaroisRadioButton}">
<BulletDecorator Cursor="Hand">
<Border BorderBrush="LightGray"
BorderThickness="2"
Margin="2">
<Grid>
<Border Grid.Row="1"
Grid.Column="0"
Margin="2"
Background="{DynamicResource buttonPressedBackBrush}"
Width="{Binding RadioMarkSize}"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
Name="LeftRadioMark"/>
<ContentPresenter Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="2"/>
</Grid>
</Border>
</BulletDecorator>
</ControlTemplate>
</Setter.Value>
</Setter>
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Try using TemplateBinding instead.
<Border
Grid.Row="1"
Grid.Column="0"
Margin="2"
Background="{DynamicResource buttonPressedBackBrush}"
Width="{TemplateBinding RadioMarkSize}"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
Name="LeftRadioMark"
/>
TemplateBinding Markup Extension | Microsoft Docs[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
That did it. Thanks! ya learnt me something
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Did you set the DataContext to your custom create class called "MaroisRadioButton" I believe in the code-behind you need to set the DataContext to this custom class so XAML engine can locate this custom dependency property.
Ben Scharbach
Temporalwars.Com
YouTube:Ben Scharbach
|
|
|
|
|
I created a UserControl with some buttons called 'ButtonBarView'. They buttons all like this:
<mctrls:MaroisImageButton Grid.Row="0"
Grid.Column="0"
Caption="New"
Style="{StaticResource NewButtonStyle}"
Command="{Binding NewCommand}"
Margin="3"/>
The control is then placed on a view which has an ICommand on it called NewCommand, yet the binding fails. The Output window shows
BindingExpression path error: 'NewCommand' property not found on 'object' ''ButtonBarView' (Name='')'. BindingExpression:Path=NewCommand; DataItem='ButtonBarView' (Name=''); target element is 'MaroisImageButton' (Name=''); target property is 'Command' (type 'ICommand')
I thought that as long as the command exists on the VM the control would find it. What am I doing 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.
|
|
|
|
|
It's already told you what is wrong in the error. It thinks that the DataContext is set to the view, not the VM.
|
|
|
|
|
Ya I had this.DataContext = this in the code behind.
I'm a dumbass
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 UserControl that contains a ListBox, a CheckBox, a TextBox, and OK & Cancel buttons. I made a few small changes to the button's control template to change the button's border and added a trigger.
This control can be used an any app, so I need to understand how to style it. Would I need to name the button and create a named style? That would be in each app that I want to use it I would have to create style elements that specifically target each element in my UserControl.
I'm not sure how styling works for generic UserControls. Can someone point me in the right direction?
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
In this WPF can be a real pain. I wanted to create a textbox that had a browse button inside of it to match some other controls and it was quite the hassle. Basically, the flow is this:
1. Create your user control, hopefully it is based off of other controls so you can use the existing dependency properties
2. In your resources.xaml file, add a reference to the xmlns of your control
3. Add style in resources.xaml
For me, my control is called a BrowseTextBox. The style looks like this:
<Style x:Key="{x:Type cont:BrowseTextBox}"
TargetType="{x:Type cont:BrowseTextBox}"
BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="Background"
Value="#FFFFFF" />
<Setter Property="Foreground"
Value="#000000" />
<Setter Property="Padding"
Value="5,3" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
<Setter Property="FocusVisualStyle"
Value="{x:Null}" />
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="KeyboardNavigation.TabNavigation"
Value="Once" />
<Setter Property="KeyboardNavigation.ControlTabNavigation"
Value="Cycle" />
<Setter Property="IsTabStop"
Value="False" />
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type cont:BrowseTextBox}">
<Grid x:Name="LayoutGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="TextColumn"
Width="*" />
<ColumnDefinition x:Name="ButtonsColumn"
Width="Auto" />
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Duration="0"
To="1"
Storyboard.TargetProperty="Opacity"
Storyboard.TargetName="MouseOverVisual" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="Focus">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Background"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1"
Background="{TemplateBinding Background}"
Grid.ColumnSpan="2" />
<Border x:Name="MouseOverVisual"
BorderThickness="1"
BorderBrush="{StaticResource TextBoxFocus}"
Background="{TemplateBinding Background}"
Grid.ColumnSpan="2"
Opacity="0" />
<Border x:Name="Focus"
BorderBrush="{StaticResource TextBoxFocus}"
BorderThickness="{TemplateBinding BorderThickness}"
Grid.ColumnSpan="2"
IsHitTestVisible="False"
Visibility="Collapsed" />
<Border x:Name="ReadOnly"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1"
Background="#FF575859"
Grid.ColumnSpan="2">
<Border.Visibility>
<Binding Path="IsReadOnly"
RelativeSource="{RelativeSource TemplatedParent}">
<Binding.Converter>
<telerik:BooleanToVisibilityConverter />
</Binding.Converter>
</Binding>
</Border.Visibility>
</Border>
<ScrollViewer x:Name="PART_ContentHost"
Grid.Column="0"
BorderBrush="Transparent" />
<Border x:Name="PART_SearchIconBorder"
Grid.Column="1"
BorderThickness="0"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch">
<telerik:RadButton x:Name="Search"
Style="{StaticResource TextButton}"
Content="..."
ToolTip="Browse"
VerticalAlignment="Stretch"
Width="15" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Mine is using some Telerik styles as that is what I am using on the rest of my form. The control in the view looks like this:
<cont:BrowseTextBox x:Name="CurrentObservation_FilePath"
Grid.Row="7"
Grid.Column="1"
HorizontalAlignment="Stretch"
Margin="2,2,0,0"
Browse="FileBrowser_OnClick" />
The user control is pretty much just the same thing you are talking about, an existing type of control (text box) with another control (button) inside of it.
|
|
|
|
|
Using MVVM I have a property to hold the value to be displayed in the ColumnGroup Text property
This fails to display the required text
<telerik:GridViewColumnGroup Name="ThisYearA" Header="{Binding Path=DataContext.lThisYearActual, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type telerik:RadGridView}}}" />
I have also bound the text to a hidden textblock, this also fails to display in the ColumnGroup
<telerik:GridViewColumnGroup Name="ThisYearF" Binding ElementName=txtLastYearActual}" />
Any suggestion as to how to bind this?
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
|
I have created a split button that looks and works like one of these. I put it up OneDrive.
I've never really done anything like this before, and I'd like to create a suite of controls. I've already created a DropDown Date/Time Picker. Now I have this done.
So for this control, use it like this:
xmlns:sb="clr-namespace:Marois.Framework.WPF.Controls.SplitButtonControl;assembly=Marois.Framework.WPF.Controls"
<sb:SplitButton Grid.Column="5"
Height="25"
Width="150"
Items="{Binding ElementName=myWindow, Path=MyItems}"
SelectedItem="{Binding ElementName=myWindow, Path=MySelectedItem, Mode=TwoWay}"
SelectedItemChanged="SplitButton_SelectedItemChanged" />
and in the code behind
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private List _MyItems;
public List MyItems
{
get { return _MyItems; }
set
{
if (_MyItems != value)
{
_MyItems = value;
RaisePropertyChanged("MyItems");
}
}
}
private SplitButtonItem _MySelectedItem;
public SplitButtonItem MySelectedItem
{
get { return _MySelectedItem; }
set
{
if (_MySelectedItem != value)
{
_MySelectedItem = value;
RaisePropertyChanged("MySelectedItem");
}
}
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
MyItems = new List
{
new SplitButtonItem(new BitmapImage(new Uri(@"left_arrow.png")), "Item 1"),
new SplitButtonItem(null, "Item 2"),
new SplitButtonItem(new BitmapImage(new Uri(@"right_arrow.png")), "Item 3"),
};
}
protected void RaisePropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private void SplitButton_SelectedItemChanged(object sender, SplitButtonControl.SplitButton.SelectionChangedEventArgs e)
{
MessageBox.Show(e.SelectedItem.Caption, "Selected Item", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
So here's the question. If you look at the XAML for the control you'll see two Templates - one for the Button portion and another for the ToggleButton. They contain various settings for colors, brushes, margins, CornerRadius, etc.
How do you create a style for this? Would you name each element and then create a style that targets each named element?
How do you create a suite of controls, then create style(s) that apply across all your controls?
Thanks!
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Why not just use the Ribbon controls (e.g. "split menu item" that looks like a "button")?
You're duplicating existing functionality.
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
Gerry Schmitz wrote: Why not just use the Ribbon controls (e.g. "split menu item" that looks like a "button")?
Have you ever used these Ribbon controls? I have. WAY WAY WAY too over cooked.
That's exactly what I'm trying to avoid - paying hundreds or thousands of dollars for control suites that have a limited set of controls and are either way too over engineered or don't do enough.
1) You almost never get all the controls you want, so you usually then have to include multiple third party controls into your app.
2) Many of them are crap (Infragistics is a good example), Telerik is OK but lacks some things
3) For what you pay for you just don't get enough. And I'm talking WITHOUT the source.
4) Tech support is almost always a nightmare.
If I have the code, and created my own suite, then I can modify it any way I want and not rely on some other vendor.
Gerry Schmitz wrote: You're duplicating existing functionality.
Not necessarily. Assuming you could purchase a complete set of controls that functioned EXACTLY the way you want, then you would be right. But I've yet to find a set of controls that is that complete.
Again, if it's just a set of controls, then how much 'functionality' are we talking a about?? If we were talking about a specialized API that was specific to some app or piece of equipment, then writing a new one would make no sense. But for a set of controls, I think I have the advantage here.
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Paying?
These are the "native" WPF Ribbon controls:
xmlns:ribbon="clr-namespace:System.Windows.Controls.Ribbon;assembly=System.Windows.Controls.Ribbon"
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
The only one talking about a Ribbon is you.
I'm talking about a Suite of controls. Most of them you buy are totally inaduquate.
But anyway, you never answered my original question
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I asked a "question": I was suggesting you could save time by using existing (free) "split buttons", etc. (that you could style).
You keep talking about $; while I said to use what is already in the framework.
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
I understand why you asked. I just think this discussion went way off the rails. At no point was my original question dealt with. It seems you we're trying to guide me down a different approach.
Gerry Schmitz wrote: use what is already in the framework.
The controls I'm working on don't exist in the framework - that's why I'm creating them.
One other reason I want to develop these controls myself is really for the learning experience.
Thanks for your input.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 19-May-17 11:21am.
|
|
|
|