我有要使用数据绑定在Canvas中显示的项目列表.
ItemsToShowInCanvas = new ObservableCollection<ItemDetail>
{
new ItemDetail {Text = "ABC", Top = 10, Left = 200},
new ItemDetail {Text = "DEF", Top = 100, Left = 300},
new ItemDetail {Text = "PQR", Top = 50, Left = 150}
};
Run Code Online (Sandbox Code Playgroud)
ItemDetail是一个简单的类,具有Text,Top和Left值的自动属性
public class ItemDetail
{
public string Text { get; set; }
public double Top { get; set; }
public double Left { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
当我对项目进行数据绑定时,它们会出现在画布中.但是这些项目不会出现在使用"上"和"左"属性提到的位置.
<Canvas>
<ItemsControl ItemsSource="{Binding Path=ItemsToShowInCanvas}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Text}" Canvas.Top="{Binding Path=Top}" Canvas.Left="{Binding …Run Code Online (Sandbox Code Playgroud) 对于Windows.Control.ToolTip似乎没有.Show()类型的方法,包括在ToolTipService中.
我对MVVM架构设计很陌生......
我最近一直在努力寻找一个已经为此目的编写的合适的控件,但没有运气,所以我从另一个类似的控件中重用了部分XAML并自己制作了.
我想要实现的是:
有一个可重用的View(usercontrol)+ viewmodel(要绑定到),以便能够在其他视图中使用作为模式覆盖,显示禁用视图其余部分的对话框,并在其上显示一个对话框.

我是如何实现它的:
pseudoXAML:
<usercontrol /customerview/ ...>
<grid>
<grid x:Name="content">
<various form content />
</grid>
<ctrl:Dialog DataContext="{Binding DialogModel}" Message="{Binding Message}" Commands="{Binding Commands}" IsShown="{Binding IsShown}" BlockedUI="{Binding ElementName=content}" />
</grid>
</usercontrol>
Run Code Online (Sandbox Code Playgroud)
因此,模态对话框从Customer视图模型的DialogModel属性获取datacontext,并绑定命令和消息.它也会绑定到对话框显示(绑定到IsShown)时需要禁用的其他元素(此处为'content').当您单击对话框中的某个按钮时,将调用关联的命令,该命令只调用在viewmodel的构造函数中传递的关联操作.
这样我就可以从Customer视图模型中调用对话框视图模型上的对话框的Show()和Hide(),并根据需要更改对话框视图模型.
它会一次只给我一个对话但是没问题.我还认为对话框视图模型将保持单一性,因为单元测试将涵盖在构造函数中使用Actions创建后应该创建的命令的调用.对话框视图会有几行代码隐藏,但很少而且非常愚蠢(setter getters,几乎没有代码).
我关心的是:
这个可以吗?我有什么问题可以进入吗?这会破坏一些MVVM原则吗?
非常感谢!
编辑:我发布了我的完整解决方案,以便您可以更好地了解.欢迎任何建筑评论.如果您看到一些可以纠正的语法,则帖子会被标记为社区维基.
显然,WPF WebBrowser控件存在一些严重的键盘和焦点问题.我整理了一个简单的WPF应用程序,只是一个WebBrowser和两个按钮.该应用程序加载一个非常基本的可编辑HTML标记(<body contentEditable='true'>some text</body>)并演示以下内容:
标签是行为不端的.用户需要按两次Tab键才能在WebBrowser中查看插入符号(文本光标)并能够键入.
当用户切换远离应用程序时(例如,使用Alt-Tab),然后返回,插入符号消失,她根本无法键入.需要物理鼠标单击WebBrowser的窗口客户端区域才能取回插入符号和击键.
不一致的是,一个虚线的焦点矩形出现在WebBrowser周围(当标签时,但不是点击时).我找不到摆脱它的方法(FocusVisualStyle="{x:Null}"没有帮助).
在内部,WebBrowser永远不会得到关注.对于逻辑焦点(FocusManager)和输入焦点(键盘)都是如此.将Keyboard.GotKeyboardFocusEvent和FocusManager.GotFocusEvent从不事件被解雇的web浏览器(虽然他们都对按钮做在同一个焦点范围).即使当插入符号是web浏览器内,FocusManager.GetFocusedElement(mainWindow)指向先前聚焦元件(按钮)和Keyboard.FocusedElement是null.同时,((IKeyboardInputSink)this.webBrowser).HasFocusWithin()回报true.
我会说,这样的行为几乎太功能无法实现,但这就是它的运作方式.我可能想出一些黑客来解决它并将其与原生WPF控件一起排成一行TextBox.我仍然希望,也许我在这里错过了一些模糊而简单的东西.有没有人处理过类似的问题?任何有关如何解决这个问题的建议将不胜感激.
此时,我倾向于为基于HwndHost的 WebBrowser ActiveX控件开发内部WPF包装器.我们还在考虑 WebBrowser的其他替代方案,例如Chromium Embedded Framework(CEF).
VS2012项目可以从这里下载,以防有人想玩它.
这是XAML:
<Window x:Class="WpfWebBrowserTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Width="640" Height="480" Background="LightGray">
<StackPanel Margin="20,20,20,20">
<ToggleButton Name="btnLoad" Focusable="True" IsTabStop="True" Content="Load" Click="btnLoad_Click" Width="100"/>
<WebBrowser Name="webBrowser" Focusable="True" KeyboardNavigation.IsTabStop="True" FocusVisualStyle="{x:Null}" Height="300"/>
<Button Name="btnClose" Focusable="True" IsTabStop="True" Content="Close" Click="btnClose_Click" …Run Code Online (Sandbox Code Playgroud) 我希望wpf按钮的内容保持对齐我尝试了以下但文本仍然在按钮内居中.
<Button >
<StackPanel HorizontalAlignment="Stretch">
<TextBlock HorizontalAlignment="Left" Text="Save"/>
</StackPanel>
</Button>
Run Code Online (Sandbox Code Playgroud)
我该怎么办?
这是我正在使用的一个例子:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<WrapPanel Orientation="Horizontal" TextElement.FontSize="30" TextElement.FontStyle="Italic" >
<Button Content="test1" Margin="10,0" Padding="10,10" />
<Button Content="test2" Margin="10,0" Padding="10,10" />
<Button Content="test3" Margin="10,0" Padding="10,10" />
<Button Content="test4" Margin="10,0" Padding="10,10" />
<Button Content="test5" Margin="10,0" Padding="10,10" />
</WrapPanel>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)
如您所见,我的包装面板有几个按钮.每个按钮具有相同的边距和填充.
问题是,有没有办法为包装面板设置边距和填充,因此包装面板内的每个元素都可以使用它的值?
为了设置内部元素的字体,我可以使用"TextElement"附加属性提供程序.有没有类似的方法我可以设置内部控件的边距和填充?
这使得代码更短,让我只指定一次Margin和Padding,而不是为面板中的每个控件设置它.
谢谢!
当我ListBox使用水平项目创建时,例如:
<DockPanel>
<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBoxItem>
<Button Content="Hello" />
</ListBoxItem>
<ListBoxItem>
<Button Content="Hello" />
</ListBoxItem>
</ListBox>
</DockPanel>
Run Code Online (Sandbox Code Playgroud)
我在列表中的按钮之间有小间隙,如下图中的箭头所示:

我怎么能摆脱这些差距呢?我需要ListBox彼此相邻的物品.我试图改变ItemTemplate的ListBox,但它并没有帮助.
我只是尝试统一网格,它是如何工作的.
代码:
<UniformGrid Name="uniformGrid1" Rows="2" Columns="3">
<Button Content="Rohit" Grid.Row="0" Grid.Column="0" />
<Button Content="asit" Grid.Row="0" Grid.Column="2" />
</UniformGrid>
Run Code Online (Sandbox Code Playgroud)
我发现两个按钮彼此相邻放置,但它们之间存在一列.为什么会这样?(在统一网格中,每个单元格大小相似,它们之间应该有一个单元格)
理解为什么它是这样(通过回答),但仍然好奇知道Attached属性的重要性 - Grid.Row&Grid.Column如果他们什么也不做?
对于我们的WPF应用程序,当它在触摸屏(Surface Pro .etc)上运行时,TextBox/ PasswordBoxcontrol 在聚焦时无法显示虚拟键盘.
在WPF中实现此功能的任何好方法?
我们最终想要实现的是这样的:
如果用户在PC上运行app,我们不关心这个功能,这意味着用户是否有物理键盘,我们什么都不做就像在PC上运行的普通WPF应用程序一样.
如果用户在Surface Pro上运行,当他点击它时TextBox,内置虚拟键盘可以显示,并且应该是用户友好的,例如键盘永远不会掩盖输入元素.
那么,WPF不能轻易设置一些属性来实现这个功能吗?在我看来,这个功能应该是内置的WPF,我不明白为什么我找不到一个简单的方法来实现.