|
The ads would come from an external web source presumably so you would just need to display a browser control in your nag screen and serve your ad there.
This space for rent
|
|
|
|
|
yeah.., all advertising thing I found seems to come from a website...
I haven't even started on the website yet and the app is not even alpha (yet).. mmm.. I guess it's too early to do anything about it...
|
|
|
|
|
You should conside UWP and the Microsoft Store, and a their "monetizing". You give up 30% on "games" and 10% on the rest. Reasonable "management" fees IMO.
Microsoft Ad Monetization platform
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
It's a good idea, but I checked many times and UWP is unfortunately a no no!
Why?
It's a document application! It needs to open file on your filesystem wherever they are. When it restart it automatically open previous document (like Visual Studio) and some important file can also be bookmarked for automatic usage of image resources.
All of that is night impossible with all the restriction to file system access that UWP apps suffer... I checked many times before
However you got a point. I think one can ship normal Desktop app in the store and have some hybrid UI (both WPF and UWP) so I might have a look.
Plus at this stage I have lot of WPF (not only XAML, but also low level custom Visual...) not sure how well it would port to UWP...
|
|
|
|
|
By "default", VS uses it's own "project folders".
If you expect to open "non-app" files on "start-up", you will need to "stage" this file locally after closing it on last use (your "MRU" list).
This needs to be done to maintain the security of the platform, and is reasonable if the user sticks with the "tool" as intended.
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
I was looking at this blog post about WPF Data Validations.
It lays out some basic methods:
Data Annotations
This is nice because you can define model requirements on the model itself. HOW those requirements are enforced is done in whatever applications use those models.
IDataErrorInfo
In this case he invokes a service that does Server Side Validation. I can see this being useful for
things like checking for duplicates against a DB, bit not for simple UI validation like ensuring
required properties on a model are set.
But I can see uses for BOTH methods in an app. The annotations handle the simple, client side validation and the service handles more complex validation in the BL.
What I can't figure out is how to combine BOTH of these. I'd really like to have a generic assembly that I can re-use to handle validation.
Anyone know of a nice example?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
yes you can.
Below find my the base ModelBase class that I use, that uses data anntoation to validate its property when OnPropertyChanged() is fired, with caveat it uses my own attributes, and might be missing some stuff.. but it should give you an idea!
public abstract class ValidationAttribute : Attribute
{
public abstract void Validate(ModelBase model, FastMember member, object value);
public string ErrorMessage { get; set; }
}
public class ModelBase : INotifyPropertyChanged, INotifyDataErrorInfo
{
#region INotifyPropertyChanged
public virtual void OnPropertyChanged([CallerMemberName]string name = "")
{
if (ValidatePropertyOnNotifyChanged)
{
if (string.IsNullOrEmpty(name))
{
Validate();
}
else
{
Validate(name);
}
}
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region ValidatePropertyOnNotifyChanged Validate()
public bool ValidatePropertyOnNotifyChanged
{
get { return mValidatePropertyOnNotifyChanged; }
set
{
if (value == mValidatePropertyOnNotifyChanged)
return;
mValidatePropertyOnNotifyChanged = value;
if (value)
Validate();
}
}
bool mValidatePropertyOnNotifyChanged;
public bool Validate()
{
ClearErrors();
foreach (var p in GetFastType().GetRuntimeMembers())
Validate(p);
return !HasErrors;
}
#endregion
#region Errors (databinding error friend)
public ErrorIndex Errors
{
get
{
if (eInfos == null)
eInfos = new ErrorIndex(this);
return eInfos;
}
}
ErrorIndex eInfos;
public class ErrorIndex : INotifyPropertyChanged
{
ModelBase model;
internal ErrorIndex(ModelBase model)
{
this.model = model;
}
public ErrorData this[string property]
{
get
{
var errs = model.GetErrors(property).Cast<object>();
return new ErrorData
{
HasError = errs.Any(),
Error = errs.FirstOrDefault(),
Errors = errs,
};
}
}
internal void Updated(string pName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(pName)); }
public event PropertyChangedEventHandler PropertyChanged;
}
public class ErrorData
{
public bool HasError { get; set; }
public object Error { get; set; }
public System.Collections.IEnumerable Errors { get; set; }
}
#endregion
#region INotifyDataErrorInfo
List<Tuple<string, object>> errors
{
get
{
if (_errors == null)
_errors = new List<Tuple<string, object>>();
return _errors;
}
}
List<Tuple<string, object>> _errors;
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
void RaiseErrorChanged(string pName)
{
pName = '[' + pName + ']';
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(pName));
OnPropertyChanged(nameof(HasErrors));
eInfos?.Updated(pName);
}
public System.Collections.IEnumerable GetErrors(string propertyName)
{
return errors.Where(x => x.Item1 == propertyName).Select(x => x.Item2);
}
public bool HasErrors { get { return errors.Count > 0; } }
public void UpdateErrors(string propertyName, params object[] errors) { UpdateErrors(propertyName, (IEnumerable<object>)errors); }
public void UpdateErrors(string propertyName, IEnumerable<object> errors)
{
bool had = false;
for (int i = this.errors.Count - 1; i >= 0; i--)
{
if (this.errors[i].Item1 == propertyName)
{
had = true;
this.errors.RemoveAt(i);
}
}
bool will = false;
if (errors != null)
{
errors.ForEach(x =>
{
will = true;
this.errors.Add(Tuple.Create(propertyName, x));
});
}
if (had || will)
{
RaiseErrorChanged(propertyName);
}
}
public void AddErrors(string propertyName, params object[] errors) { AddErrors(propertyName, (IEnumerable<object>)errors); }
public void AddErrors(string propertyName, IEnumerable<object> errors)
{
if (errors == null || errors.Count() == 0)
return;
errors.ForEach(x => this.errors.Add(Tuple.Create(propertyName, x)));
RaiseErrorChanged(propertyName);
}
public void ClearErrors(string propertyName)
{
int count = 0;
for (int i = errors.Count - 1; i >= 0; i--)
{
if (errors[i].Item1 == propertyName)
{
errors.RemoveAt(i);
count++;
}
}
if (count > 0)
RaiseErrorChanged(propertyName);
}
public void ClearErrors()
{
var names = errors.Select(x => x.Item1).Distinct().ToList();
errors.Clear();
names.ForEach(x => RaiseErrorChanged(x));
}
public bool Validate([CallerMemberName]string propertyName = null)
{
if (propertyName == null)
return Validate();
var m = GetFastType().GetRuntimeMembers().First(x => x.Name == propertyName);
ClearErrors(propertyName);
Validate(m);
return !GetErrors(propertyName).Cast<object>().Any();
}
FastType GetFastType() { return meType ?? (meType = FastType.GetType((GetType()))); }
FastType meType;
protected virtual void Validate(FastMember pi)
{
if (pi == null)
return;
var value = pi.GetValue(this);
var attrs = pi.GetAttributes().OfType<ValidationAttribute>();
foreach (var attr in attrs)
attr.Validate(this, pi, value);
}
#endregion
#region extra utilities: GetLazyCommand() AddWatch()
public DelegateCommand GetLazyCommand(Action onAction, [CallerMemberName]string name = null)
{
if (mCommands == null)
mCommands = new Dictionary<string, DelegateCommand>();
if (!mCommands.TryGetValue(name, out var result))
mCommands[name] = result = new DelegateCommand(onAction);
return result;
}
public DelegateCommand GetLazyCommand(Action<object> onAction, [CallerMemberName]string name = null)
{
if (mCommands == null)
mCommands = new Dictionary<string, DelegateCommand>();
if (!mCommands.TryGetValue(name, out var result))
mCommands[name] = result = new DelegateCommand(onAction);
return result;
}
public DelegateCommand GetLazyCommandAsync(Func<Task> onAction, [CallerMemberName]string name = null)
{
if (mCommands == null)
mCommands = new Dictionary<string, DelegateCommand>();
if (!mCommands.TryGetValue(name, out var result))
{
var cmd = new DelegateCommand();
cmd.Action = async (o) =>
{
try
{
cmd.IsEnabled = false;
await onAction();
}
finally { cmd.IsEnabled = true; }
};
mCommands[name] = result = cmd;
}
return result;
}
Dictionary<string, DelegateCommand> mCommands;
public void AddWatch<TP>(Expression<Func<TP>> e, Action<TP> onChange)
{
if (watchers == null)
watchers = new List<PropertyPath>();
var w = PropertyPath.Create(e);
watchers.Add(w);
w.PropertyChanged += delegate { onChange(w.Value); };
}
List<PropertyPath> watchers;
#endregion
}
|
|
|
|
|
Here's my two extension methods for checking if a property or an IDataErrorInfo object has any errors:
public static bool HasErrors( this IDataErrorInfo dataObject ) {
Type dataObjectType = dataObject.GetType();
PropertyInfo[] pInfo = dataObjectType.GetProperties( BindingFlags.Public | BindingFlags.Instance );
foreach ( PropertyInfo p in pInfo ) {
if ( p.CanWrite ) {
if ( string.IsNullOrEmpty( dataObject[ p.Name ] ) == false ) {
return true;
}
}
}
return false;
}
public static bool HasErrors( this IDataErrorInfo dataObject, string name ) {
if ( string.IsNullOrEmpty( dataObject[ name ] ) == false ) {
return true;
}
return false;
}
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
<DataGrid Grid.Column="1" x:Name="GrdInsCardsLookup" AutoGenerateColumns="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MaxWidth="600" Margin="3,6,3,-1" Background="{x:Null}">
<DataGrid.BorderBrush>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFE22020" Offset="1"/>
</LinearGradientBrush>
</DataGrid.BorderBrush>
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Width="130" Binding="{Binding NationalId}"/>
<DataGridTextColumn Header="Name" Width="140" Binding="{Binding Name}"/>
<DataGridTextColumn Header="Phone" Width="120" Binding="{Binding Phone}"/>
<DataGridTextColumn Header="City" Width="100" Binding="{Binding City}"/>
</DataGrid.Columns>
</DataGrid>
public class Instructer
{
public int Id { set; get; }
public string NationalId { set; get; }
public string Name { set; get; }
public string Fname { set; get; }
public string Lname { set; get; }
public string FatherName { set; get; }
public int Cityid { set; get; }
public string City { set; get; }
public string Address { set; get; }
public string Email { set; get; }
public string Phone { set; get; }
public string Mobile { set; get; }
public DateTime Birthday { set; get; }
public string Picid { set; get; }
public string Folder { set; get; }
}
public DataSet AllInsDataSet = new DataSet();
public List<Instructer> InstructersByName = new List<Instructer>();
private void FillInsList()
{
AllInsDataSet.Clear();
var con1 = new SqlConnection(Connectionstring);
SqlCommand cmd1;
cmd1 =
new SqlCommand(
"SELECT S1.[ins_id],S1.[ins_national_id],S1.[fname] as FName,S1.[father_name] as 'FatherName',S1.[lname] as 'LName',S1.[city_id],C1.[city],S1.[address],S1.[email],S1.[phone],S1.[mobile],S1.[birthday],S1.[pic_id],S1.[folder_id],S1.[other] FROM [DB_SchoolManager].[dbo].[tbl_ins_cards] S1 Inner Join [DB_SchoolManager].[dbo].[tbl_cities] C1 on S1.city_id=C1.city_id",
con1);
SqlDataAdapter da1;
da1 = new SqlDataAdapter(cmd1);
da1.Fill(AllInsDataSet);
}
private void FillLookupInsGrdByName(string name)
{
InstructersByName.Clear();
GrdStuCardsLookup.ItemsSource = InstructersByName;
string upname = name.ToUpper();
for (int i = 0; i < AllInsDataSet.Tables[0].Rows.Count; i++)
{
if (((AllInsDataSet.Tables[0].Rows[i][2] + " " + AllInsDataSet.Tables[0].Rows[i][3] + " " + AllInsDataSet.Tables[0].Rows[i][4]).ToUpper()).Contains(upname))
{
InstructersByName.Add(new Instructer()
{
Id = int.Parse(AllInsDataSet.Tables[0].Rows[i][0].ToString()),
NationalId = AllInsDataSet.Tables[0].Rows[i][1].ToString(),
Name = AllInsDataSet.Tables[0].Rows[i][2] + " " + AllInsDataSet.Tables[0].Rows[i][3] + " " + AllInsDataSet.Tables[0].Rows[i][4],
City = AllInsDataSet.Tables[0].Rows[i][6].ToString(),
Phone = AllInsDataSet.Tables[0].Rows[i][9].ToString(),
Picid = AllInsDataSet.Tables[0].Rows[i][12].ToString(),
Folder = AllInsDataSet.Tables[0].Rows[i][13].ToString()
});
}
}
GrdInsCardsLookup.ItemsSource = InstructersByName;
}
private void TxtSrchInsName_TextChanged(object sender, TextChangedEventArgs e)
{
if (!String.IsNullOrEmpty(TxtSrchInsName.Text))
{
SrchName = TxtSrchInsName.Text;
FillLookupInsGrdByName(SrchName);
}
}
|
|
|
|
|
so.. what is the exception you are getting?
From the look of it, it looks like you are binding to a list which has been updated after being given to the UI.
Hence the UI display the original list, that do not match the current list.
To solve that problem use a class implementing INotifyCollectionChanged . I recommend ObservableCollection<T> instead of List<T>
|
|
|
|
|
First thank you very much
i dont no the deference between List<t> and ObservableCollection<t> but it works
|
|
|
|
|
ObservableCollection<T> implements INotifyCollectionChanged
This is the interface that helps ListItem s synchronise with lists.
Glad it fixed your problem!
In visual studio, press "F12" when the cursor is on an unknown class and watch and learn!
"F1" will also be interesting if the class is part of Microsoft API...
|
|
|
|
|
You've posted the same question twice, and still managed to not provide the details of the exception.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
XML Code
<DataGrid Grid.Column="1" x:Name="GrdInsCardsLookup" AutoGenerateColumns="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MaxWidth="600" Margin="3,6,3,-1" Background="{x:Null}">
<DataGrid.BorderBrush>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFE22020" Offset="1"/>
</LinearGradientBrush>
</DataGrid.BorderBrush>
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Width="130" Binding="{Binding NationalId}"/>
<DataGridTextColumn Header="Name" Width="140" Binding="{Binding Name}"/>
<DataGridTextColumn Header="Phone" Width="120" Binding="{Binding Phone}"/>
<DataGridTextColumn Header="City" Width="100" Binding="{Binding City}"/>
</DataGrid.Columns>
</DataGrid>
C# Code
public DataSet AllInsDataSet = new DataSet();
public List<Instructer> InstructersByName = new List<Instructer>();
private void FillInsList()
{
AllInsDataSet.Clear();
var con1 = new SqlConnection(Connectionstring);
SqlCommand cmd1;
cmd1 =
new SqlCommand(
"SELECT S1.[ins_id],S1.[ins_national_id],S1.[fname] as FName,S1.[father_name] as 'FatherName',S1.[lname] as 'LName',S1.[city_id],C1.[city],S1.[address],S1.[email],S1.[phone],S1.[mobile],S1.[birthday],S1.[pic_id],S1.[folder_id],S1.[other] FROM [DB_SchoolManager].[dbo].[tbl_ins_cards] S1 Inner Join [DB_SchoolManager].[dbo].[tbl_cities] C1 on S1.city_id=C1.city_id",
con1);
SqlDataAdapter da1;
da1 = new SqlDataAdapter(cmd1);
da1.Fill(AllInsDataSet);
}
private void FillLookupInsGrdByName(string name)
{
InstructersByName.Clear();
GrdStuCardsLookup.ItemsSource = InstructersByName;
string upname = name.ToUpper();
for (int i = 0; i < AllInsDataSet.Tables[0].Rows.Count; i++)
{
if (((AllInsDataSet.Tables[0].Rows[i][2] + " " + AllInsDataSet.Tables[0].Rows[i][3] + " " + AllInsDataSet.Tables[0].Rows[i][4]).ToUpper()).Contains(upname))
{
InstructersByName.Add(new Instructer()
{
Id = int.Parse(AllInsDataSet.Tables[0].Rows[i][0].ToString()),
NationalId = AllInsDataSet.Tables[0].Rows[i][1].ToString(),
Name = AllInsDataSet.Tables[0].Rows[i][2] + " " + AllInsDataSet.Tables[0].Rows[i][3] + " " + AllInsDataSet.Tables[0].Rows[i][4],
City = AllInsDataSet.Tables[0].Rows[i][6].ToString(),
Phone = AllInsDataSet.Tables[0].Rows[i][9].ToString(),
Picid = AllInsDataSet.Tables[0].Rows[i][12].ToString(),
Folder = AllInsDataSet.Tables[0].Rows[i][13].ToString()
});
}
}
GrdInsCardsLookup.ItemsSource = InstructersByName;
}
public class Instructer
{
public int Id { set; get; }
public string NationalId { set; get; }
public string Name { set; get; }
public string Fname { set; get; }
public string Lname { set; get; }
public string FatherName { set; get; }
public int Cityid { set; get; }
public string City { set; get; }
public string Address { set; get; }
public string Email { set; get; }
public string Phone { set; get; }
public string Mobile { set; get; }
public DateTime Birthday { set; get; }
public string Picid { set; get; }
public string Folder { set; get; }
}
modified 16-Dec-18 7:53am.
|
|
|
|
|
My form has a ScrollViewer (horizontally oriented), with elements consisting of a set of UserControls. Basically layed out like this:
<ScrollViewer Name="TrackScroller" . . .
<Grid x:Name="TrackGrid" . . .
<Grid.ColumnDefinitions>
...
<local:TrackModule x: . . .
What I'd like to know, before I delve into it and possibly make myself crazy, is it possible to reorder the elements (the TrackModules) by dragging them to new positions in the grid? And, if so, will everything adjust itself afterward automatically?
Searching, I find tons of stuff about reordering DataGrid columns, but this isn't a DataGrid, and reordering rows of plain vanilla Grids, but nothing about columns.
Is what I'm thinking of doing even possible? (This is just a feature I'm idly thinking about, nothing even close to vital, so ROI is a factor, too.)
|
|
|
|
|
Normal panels are not quite friendly to drag operation (except perhaps canvas panel)
But I can imagine that one could create an adorner on mouse down, drag the adorner on mouse drag, update items Grid.Column on mouse up of the adorner
if you don't know about adorners:
Adorners Overview | Microsoft Docs
|
|
|
|
|
Thanks. I'll look into it.
|
|
|
|
|
Can someone show me how to create a Border with a background that pulsates from one color to another. I'm looking for a two-color fade in/out. The colors must be bound to property.
The colors will be set in response to a Status DP being changed.
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Find below a simple pulsing brush class I am using
public class PulsedBrush
{
public PulsedBrush()
{
Brush = new SolidColorBrush();
}
public PulsedBrush(Func<double, Color> get)
: this()
{
GetColor = get;
Update();
}
public Func<double, Color> GetColor { get; set; }
public SolidColorBrush Brush { get; private set; }
public static double DaySeconds
{
get
{
return DateTime.Now.TimeOfDay.Ticks / (double)TimeSpan.TicksPerSecond;
}
}
public void Update()
{
if (GetColor != null)
{
Brush.Color = GetColor(DaySeconds);
}
}
}
And simply call the Update() method on the CompositionTarget.Rendering event
|
|
|
|
|
I have a list of booleans, and I want to bind checkboxes to this list.\
Code Behind
private List<bool> _OnOffValues;
public List<bool> OnOffValues
{
get { return _OnOffValues; }
set
{
if (_OnOffValues != value)
{
_OnOffValues = value;
RaisePropertyChanged("OnOffValues");
}
}
}
public MyControl()
{
InitializeComponent();
this.DataContext = this;
OnOffValues = new List<bool>();
for (int x = 0; x < 24; x++)
{
OnOffValues.Add(true);
}
}
XAML
<CheckBox Grid.Row="0"
Grid.Column="0"
IsChecked="{Binding OnOffValues[0], ElementName=control}"/>
The output window shows
System.Windows.Data Error: 17 : Cannot get 'Item[]' value (type 'Boolean') from 'OnOffValues' (type 'List`1'). BindingExpression:Path=OnOffValues[0]; DataItem='MyControl' (Name='control'); target element is 'CheckBox' (Name=''); target property is 'IsChecked' (type 'Nullable`1') ArgumentOutOfRangeException:'System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: index'
The code in the contructor runs and the list is populated, but the output message appears BEFORE that.
What am I doing wrong here??
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Your binding assumes that OnOffValues is a dependency property of the control.
"As beings of finite lifespan, our contributions to the sum of human knowledge is one of the greatest endeavors we can undertake and one of the defining characteristics of humanity itself"
|
|
|
|
|
There's nothing there that says it's expecting a DP.
This space for rent
|
|
|
|
|
Look at his binding, IsChecked="{Binding OnOffValues[0], ElementName=control}" and the property, OnOffValues , is in the code behind of his user control. If he changes the property to a dependency property he won't get the error.
"As beings of finite lifespan, our contributions to the sum of human knowledge is one of the greatest endeavors we can undertake and one of the defining characteristics of humanity itself"
|
|
|
|
|
As explained below, it looks like he's using INPC so this is completely irrelevant.
This space for rent
|
|
|
|
|
Something like this,
Code behind
public partial class SomeControl : UserControl
{
public SomeControl()
{
InitializeComponent();
for (int i = 0; i < 20; i++)
{
OnOffValues.Add(true);
}
}
public List<bool> OnOffValues
{
get { return (List<bool>)GetValue(OnOffValuesProperty); }
set { SetValue(OnOffValuesProperty, value); }
}
public static readonly DependencyProperty OnOffValuesProperty =
DependencyProperty.Register("OnOffValues", typeof(List<bool>),
typeof(SomeControl), new PropertyMetadata(new List<bool>()));
}
XAML
<CheckBox IsChecked="{Binding Path=OnOffValues[0], RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"/>
"As beings of finite lifespan, our contributions to the sum of human knowledge is one of the greatest endeavors we can undertake and one of the defining characteristics of humanity itself"
|
|
|
|
|