|
I wish they would just internationalize the application; I even offered to do it but they won't give me the source code (even though they know my long history of programming experience). The computer has IE10 on it and the only thing I see is a menu option that says "Zoom (100%)" but it is grayed out.
|
|
|
|
|
Am using Datagrid,where am getting an extra column header at the end.i bind the values from server to Datagrid thru 'Tag' property.How to remove the extra column header in this case.
|
|
|
|
|
A DataGrid Column could be hidden, but I dont think you can remove it...
|
|
|
|
|
The DataGrid by default generates its columns automatically. If you set its 'AutoGenerateColumns'-Property to False you can prevent this and maybe the extra column disappears by doing so.
Additionally you can define all the columns manually like so:
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="Test" />
<DataGridTextColumn Header="Test2" />
</DataGrid.Columns>
</DataGrid>
If you disable auto generation and define your own columns there should appear no additional columns in the DataGrid.
|
|
|
|
|
Are WinForms components inside a WinformsHost element rendered with maximum possible z-index?
They always seem to overlap any WPF wlement, even with a higher Z-Index. Anyways to fix this? This is really causing much trouble when trying to embed a lengthy WinFormsHost component in a scrollable.
Beauty cannot be defined by abscissas and ordinates; neither are circles and ellipses created by their geometrical formulas.
Source
modified 18-Jul-13 21:45pm.
|
|
|
|
|
It's called the Airspace issue. It's fixed in .NET 4.5.
|
|
|
|
|
XP doesn't support .NET 4.5. Does it?
Beauty cannot be defined by abscissas and ordinates; neither are circles and ellipses created by their geometrical formulas.
Source
|
|
|
|
|
|
Pete O'Hanlon wrote: It's fixed in .NET 4.5.
Are you sure? From what I've seen, there was a fix in the beta, but they removed it from the final release.
1.3.10 Windows Presentation Foundation (WPF)
1.3.10.1 HwndHost feature has been removed from WPF in the .NET Framework 4.5 Beta
The .NET Framework 4.5 Developer Preview included a WPF HwndHost redirection feature. However, this feature had several known issues and has been removed from the .NET Framework 4.5 Beta. It will not be included in any future releases.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
You're right. Pete Brown, at Microsoft, promised me this would be in and as it wasn't something that I was affected by, I didn't follow up to see if it was delivered. This makes me pretty angry.
|
|
|
|
|
Pete O'Hanlon wrote: Pete Brown, at Microsoft, promised me this would be in
There's your mistake - never trust anyone called "Pete"!
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
There's an excellent article here[^] on how to mitigate the airspace issue.
|
|
|
|
|
I have several datatemplates defined in a resource dictionary (in Resources project)
My application is in a separate project that references the Resources project. Appropriate datatempalte is loaded depending upon the object that is set to the datacontext during run time. Some of these datatemplates have buttons. How do I handle the click event of these buttons. I tried eventsetter but got XAML errors abt not being able to set eventhandler.
Thanks
|
|
|
|
|
Templates work only with triggers. These triggers are use to set various properties of the button.
See this for a more detailed understanding:Triggers in WPF[^]
ClickEvent is handled in code. It is completely independent from Triggers. You should be able to attach an event handler in the XAML declaration like this.
<Button x:Name="button1" Click="button1_onClick" Template={StaticResource MyTemplate} />
In code:
private void button1_onClick(object sender, RoutedEventArgs e)
{
}
See MSDN for more details:
Button Class[^]
ButtonBase.Click Event[^]
Beauty cannot be defined by abscissas and ordinates; neither are circles and ellipses created by their geometrical formulas.
Source
|
|
|
|
|
Thanks Amitosh S.M. for your reply.
I ended up binding a command to the button in datatemplate. And then defining this command as a property in my class. Worked pretty well.
<Button Name="btnControl" Canvas.ZIndex="10" Canvas.Left="175" Canvas.Top="25" Content="ICOM"
MaxWidth="75" MaxHeight="75" Style="{StaticResource ICOMButtonStyle}" Command="{Binding LaunchControlModule}"/>
Public ReadOnly Property LaunchControlModule() As ICommand
Get
Return New ViewModelCommand(AddressOf HandlerLaundControlModule)
End Get
End Property
Private Sub HandlerLaundControlModule()
ShowControlModule = True
End Sub
Public Class ViewModelCommand
Implements ICommand
Private _handler As Action
Public Sub New(ByVal handler As Action)
_handler = handler
End Sub
#Region "ICommand Members"
Public Function CanExecute(ByVal parameter As Object) As Boolean Implements System.Windows.Input.ICommand.CanExecute
Return True
End Function
Public Event CanExecuteChanged(ByVal sender As Object, ByVal e As System.EventArgs) Implements System.Windows.Input.ICommand.CanExecuteChanged
Public Sub Execute(ByVal parameter As Object) Implements System.Windows.Input.ICommand.Execute
_handler()
End Sub
#End Region
|
|
|
|
|
I'd like to get your thoughts on this design...
So I am writing some software for personal use. I'm an independent developer, and I wanted to put together an app to track the work I'm doing and handle invoicing and billing. Conceptually I understand what I want, but programmatically I am working on the design. This is more about me learning than producing an app.
So, I am building this WPF/MVVM app in components. Most pieces are user controls. I decided that I would use relay messages to communicate between the user control a& its host.
For example, the Client View is found in the Client Center.
Each Client is viewed in its own tab in the Client Center. The Client Center has a toolbar with New, Edit, Save, Cancel and Print buttons. Since the center doesn't really know about the Client views in the tabs, the Center will broadcast a message for each function. The Client Center has an instance of a TabManager class, which is a collection of TabItems. The TabItem's Tag property contains the PK of the entity in the tab's content. So, this is available in the View Model.
As an example, when the Save button on the Client Center toolbar is clicked, then it does:
ClientViewSaveMessage message = new ClientViewSaveMessage
{
Clientid = getActiveTabEntityPK()
};
Messenger.Instance.Send<ClientViewSaveMessage>(message);
Then in the client view I have
public ClientViewModel
{
messenger.Instance.Register<ClientViewSaveMessage>(p => receiveSaveMessage(ClientViewSaveMessage)p)
}
and then the receiveSaveMessage
private void receiveSaveMessage(ClientViewSaveMessage message)
{
if(this.Client.Id == message.ClientId)
{
saveChanges();
}
}
This technique has the advantage of decoupling all the components. So far it's working well. It's easy to develop, and so far, easy to maintain.
A drawback might be that I will need a lot of messages. I could make one message that has different properties...
Any way, I'd like to hear what you guys think.
Thanks
If it's not broken, fix it until it is
|
|
|
|
|
2 things come to mind. You have low expectations of your client base (reasonable in an independant developer) as you are using a tabcontrol as your client collection UI. I would use a grid. In the late 90 after about 5 years of consulting I had well over 50 organisations I was keeping tabs on, once a client or even a quote always a potential.
One reason not to use a messaging paradigm is that it is a bitch to maintain, there is no direct link between the firer of the message and the consumer of that message. a bitch to support.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Mycroft Holmes wrote: You have low expectations of your client base (reasonable in an independant
developer) as you are using a tabcontrol as your client collection UI
I never said that. I said when a client is opened, it's opened in a new tab in the client center. There is a list of clients on the side .
Mycroft Holmes wrote: One reason not to use a messaging paradigm is that it is a bitch to maintain,
there is no direct link between the firer of the message and the consumer of
that message. a bitch to support.
That's what I said in my OP. Other than that, I cannot see any reason not to use this design,
If it's not broken, fix it until it is
|
|
|
|
|
Kevin Marois wrote: There is a list of clients on the side
Ah somewhat like the outlook bar, that makes sense.
Kevin Marois wrote: Other than that,
Yeah but support is a major factor in the cost of an app and we will go a long way to make it easier for the next poor sod who has to support the app.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
SO far it seems to be working well. Overall it's very little code, but the number of message classes is growing. I think that's where the confusion might come in. I could make one generic message class.
As far as knowing who sent a message, the call stack shows that. But I understand what you're saying.
If it's not broken, fix it until it is
|
|
|
|
|
Kevin
Can you describe in one paragraph how you constructed your dynamic tab control. I have a similar requirement (max 5 tabs). If so please email me direct (your email is disabled on the messages).
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
I'm not sure what you mean by "constructed your dynamic tab control.
If it's not broken, fix it until it is
|
|
|
|
|
I was under the impression your tabcontrol populated the tabs and content based on data rather than at design time. I have a number of ideas how to achieve this but I am trying to reduce the experimentation time required to get it working and was hoping you had already researched this and had some guidance or links to examples you had used.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Ok, I see
My tab control is bound to a class, so in the XAML I have
<TabControl Grid.Row="2"
Grid.Column="2"
x:Name="MyTabControl"
BorderBrush="#6593CF"
Background="White"
ItemsSource="{Binding TabManager.Tabs}"
SelectedItem="{Binding TabManager.ActiveTab}"
Margin="2"/>
My Tab Manager class is this
public class ViewManager : BindableBase, ITabManager
{
#region Events
public event EventHandler TabActivated;
#endregion
#region Bound Properties
private ObservableCollection<TabItem> _Tabs = new ObservableCollection<TabItem>();
public ObservableCollection<TabItem> Tabs
{
get { return _Tabs; }
set
{
if (_Tabs != value)
{
_Tabs = value;
RaisePropertyChanged("Tabs");
}
}
}
private TabItem _ActiveTab;
public TabItem ActiveTab
{
get { return _ActiveTab; }
set
{
if (_ActiveTab != value)
{
_ActiveTab = value;
RaisePropertyChanged("ActiveTab");
if (TabActivated != null)
{
TabActivated(this, new EventArgs());
}
}
}
}
private bool _TabsVisible;
public bool TabsVisible
{
get { return _TabsVisible; }
set
{
if (_TabsVisible != value)
{
_TabsVisible = value;
RaisePropertyChanged("TabsVisible");
}
}
}
#endregion
#region Public Methods
public void ActivateTab(ViewInfo TabInfo)
{
var tab = GetTab(TabInfo);
ActiveTab = tab;
}
public void AddTab(TabItem Tab, bool Activate = true, int IndexPosition = -1)
{
if (IndexPosition == -1)
{
Tabs.Add(Tab);
}
else
{
Tabs.Insert(IndexPosition, Tab);
}
if (Activate)
{
ActivateTab((ViewInfo)Tab.Tag);
TabsVisible = Tabs.Count > 0;
}
}
public bool CloseAllButThisTab(ViewInfo TabInfo)
{
bool retVal = true;
for (int i = Tabs.Count - 1; i >=0; i-- )
{
var tab = Tabs[i];
var tabInfo = (ViewInfo)tab.Tag;
if (tabInfo.View == TabInfo.View && tabInfo.EntityId == TabInfo.EntityId)
{
continue;
}
else
{
retVal = CloseTab(tabInfo);
if (!retVal)
{
break;
}
}
}
return retVal;
}
public bool CloseAllTabs()
{
bool retVal = true;
for(int i = Tabs.Count - 1; i > 0; i--)
{
var tab = Tabs[i];
retVal = CloseTab((ViewInfo)tab.Tag);
}
return retVal;
}
public bool CloseTabAtIndex(int Index)
{
Tabs.RemoveAt(Index);
return true;
}
public bool CloseActiveTab()
{
return CloseTab((ViewInfo)ActiveTab.Tag);
}
public bool CloseTab(ViewInfo TabInfo)
{
bool retVal = true;
var tab = GetTab(TabInfo);
if (tab != null)
{
ActivateTab((ViewInfo)tab.Tag);
var view = (UserControl)tab.Content;
if (view.DataContext is _CenterViewModelBase)
{
_CenterViewModelBase centerVM = (_CenterViewModelBase)view.DataContext;
for(int i = centerVM.TabManager.Tabs.Count - 1; i > -1 ; i--)
{
TabItem centerTab = centerVM.TabManager.Tabs[i];
bool closed = centerVM.TabManager.CloseTab((ViewInfo)centerTab.Tag);
if (!closed)
{
retVal = false;
break;
}
}
}
else
{
dynamic vm = (_DataEntryViewModelBase)view.DataContext;
retVal = vm.PromptSaveChanges(true);
}
if (retVal)
{
Tabs.Remove(tab);
TabsVisible = Tabs.Count > 0;
}
}
return retVal;
}
public bool HasDirtyTabs()
{
bool retVal = false;
foreach(var tab in Tabs)
{
ActivateTab((ViewInfo)tab.Tag);
var view = (UserControl)tab.Content;
_DataEntryViewModelBase vm = (_DataEntryViewModelBase)view.DataContext;
retVal = vm.IsDirty();
if (retVal)
{
break;
}
}
return retVal;
}
public bool IsTabOpen(ViewInfo TabInfo)
{
TabItem tabItem = GetTab(TabInfo);
return tabItem != null;
}
public TabItem GetTab(ViewInfo TabInfo)
{
TabItem retVal = null;
foreach (var tab in Tabs)
{
ViewInfo vi = (ViewInfo)tab.Tag;
if (vi.View == TabInfo.View && vi.EntityId == TabInfo.EntityId)
{
retVal = tab;
break;
}
}
return retVal;
}
public void RefreshTabInfo(AppMessageArgs Args)
{
foreach (var tab in Tabs)
{
UserControl view = tab.Content as UserControl;
_DataEntryViewModelBase vm = view.DataContext as _DataEntryViewModelBase;
ViewInfo vi = (ViewInfo)tab.Tag;
if (vi.View == Args.ViewType)
{
tab.Header = vm.GetEntityCaption(); ;
vi.EntityId = vm.GetEntityId();
tab.Tag = vi;
}
}
}
public bool SaveAllOpenTabs()
{
bool retVal = false;
foreach (var tab in Tabs)
{
ActivateTab((ViewInfo)tab.Tag);
var view = (UserControl)tab.Content;
_DataEntryViewModelBase vm = (_DataEntryViewModelBase)view.DataContext;
retVal = vm.PromptSaveChanges(true);
if (!retVal)
{
break;
}
}
return retVal;
}
#endregion
}
Then when I want to add a tab from a VM I do this:
private void loadView(BOMArgs Args)
{
ViewInfo tabInfo = new ViewInfo
{
View = View.BOM,
EntityId = Args.BOM.Id
};
if (tabInfo.EntityId > 0 && TabManager.IsTabOpen(tabInfo))
{
TabManager.ActivateTab(tabInfo);
}
else
{
BOMViewModel vm = new BOMViewModel(Engine);
vm.Load(Args);
UserControl view = new BOMView();
view.DataContext = vm;
TabItem tabItem = new TabItem
{
Header = vm.GetEntityCaption(),
Content = view,
Tag = tabInfo
};
TabManager.AddTab(tabItem, true);
}
}
Works perfect, although I need to de-couple the view => vm dependency in the 'else' section.
If it's not broken, fix it until it is
|
|
|
|
|
Excellent, thanks for the info, it clarified my design immensely. Have a bunch of 5s
Never underestimate the power of human stupidity
RAH
|
|
|
|