对于在视图模型中引发INotifyPropertyChanged.PropertyChanged的简单.NET属性是否足够,人们是否有任何指导? 那么你什么时候想要移动到一个完整的依赖项属性? 或者DP是主要用于观看?
我们有一个标准的MVVM模式的WPF应用程序,利用视图 – > ViewModel分辨率的Cinch(因此MefedMVVM)。 这效果很好,我可以将相关的控件绑定到ViewModel上的属性。 在特定的视图中,我们有一个Infragistics XamGrid。 此网格绑定到ViewModel上的ObservableCollection,并显示相应的行。 然而,然后我在这个网格上有一个特定的列,我试图将一个TextBox文本值绑定到父DataContext,而不是ObservableCollection属性。 此绑定失败。 我们已经通过了几个选项,其中包括: 使用AncestorType来跟踪树,并绑定到父UserControl的DataContext像这样(从这个问题,以及这一个 伟大的答案 )… {Binding Path=PathToProperty, RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}} 指定ElementName并尝试直接定位顶层控件。 看看这里,如果你想阅读关于使用ElementName。 使用在UserControl的资源中定义的“代理”FrameorkElement,根据需要尝试“传入”上下文。 我们将元素定义如下,然后引用为静态资源… <FrameworkElement x:Key="ProxyContext" DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource Self}}"></FrameworkElement> 在这种情况下,绑定findFrameworkElement,但不能访问超出的内容(当指定Path时)。 经过阅读,看起来很有可能是由Infragistics XamGrid构build列的外部树引起的。 但是,即使是这样的情况下,至less选项2或3应该工作。 我们最后的想法是它与V-VM绑定有关,但即使使用Snoop,我们仍然没有find确切的问题。 我绝不是WPF绑定的专家,所以任何指针,将不胜感激。 编辑:我发现了一些来自Infragistics的模板示例,我会尝试。 编辑2:正如@Dtex指出的,模板是要走的路。 这里是与XamGrid一起使用的相关代码片段: <ig:GroupColumn Key="CurrentDate"> <ig:GroupColumn.HeaderTemplate> <DataTemplate> <TextBlock Text="{Binding Path=DataContext.CurrentDateTest, RelativeSource={RelativeSource AncestorType=UserControl}}" /> </DataTemplate> </ig:GroupColumn.HeaderTemplate> <ig:GroupColumn.Columns> 我已经把XML打开了,你只需要添加你想要的列,然后closures相关的标签。
以下DataTemplate.DataTrigger使年龄显示为红色,如果它等于 30。 如果年龄大于 30岁,我该如何使年龄显示为红色? <DataTemplate DataType="{x:Type local:Customer}"> <Grid x:Name="MainGrid" Style="{StaticResource customerGridMainStyle}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="100"/> <ColumnDefinition Width="150"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <TextBlock Grid.Column="0" Grid.Row="0" Text="First Name" Margin="5"/> <TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding FirstName}" Margin="5"/> <TextBlock Grid.Column="0" Grid.Row="1" Text="Last Name" Margin="5"/> <TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding LastName}" Margin="5"/> <TextBlock Grid.Column="0" Grid.Row="2" Text="Age" Margin="5"/> <TextBlock x:Name="Age" Grid.Column="1" Grid.Row="2" […]
以前也有类似的问题,但是这个问题试图探索更多的select和传递复杂对象的能力。 问题是如何传递参数,但它确实需要分成三部分。 在XAML应用程序的页面之间导航时,如何传递参数? 使用Uri导航和手动导航有什么区别? 使用Uri导航时,如何传递对象(不只是string)? Uri导航的例子 page.NavigationService.Navigate(new Uri("/Views/Page.xaml", UriKind.Relative)); 手动导航示例 page.NavigationService.Navigate(new Page()); 这个问题的答案适用于WP7,silverlight,WPF和Windows 8。 注意:Silverlight和Windows8是有区别的 Windows Phone:页面被导航到使用Uri,数据作为查询string或实例传递 Windows 8 :通过传递types和参数作为对象来导航页面
我正在使用MVVM模式在WPF桌面应用程序上工作。 我想基于在TextBox键入的文本筛选ListView的一些项目。 我希望ListView项目被过滤,因为我改变了文本。 我想知道如何在filter文本更改时触发filter。 ListView绑定到一个CollectionViewSource ,绑定到ViewModel上的ObservableCollection 。 filter文本的TextBox绑定到ViewModel上的一个string,它应该是UpdateSourceTrigger=PropertyChanged 。 <CollectionViewSource x:Key="ProjectsCollection" Source="{Binding Path=AllProjects}" Filter="CollectionViewSource_Filter" /> <TextBox Text="{Binding Path=FilterText, UpdateSourceTrigger=PropertyChanged}" /> <ListView DataContext="{StaticResource ProjectsCollection}" ItemsSource="{Binding}" /> Filter="CollectionViewSource_Filter"链接到后面的代码中的事件处理程序,它只是在ViewModel上调用filter方法。 当FilterText的值发生变化时进行筛选 – FilterText属性的setter调用一个FilterList方法,该方法遍历ViewModel中的ObservableCollection ,并在每个ViewModel项上设置一个boolean FilteredOut属性。 我知道FilteredOut属性在filter文本更改时更新,但List不刷新。 CollectionViewSourcefilter事件只有在重新加载UserControl的时候才会被触发。 我已经尝试更新filter信息后调用OnPropertyChanged("AllProjects") ,但它并没有解决我的问题。 (“AllProjects”是我的ViewModel的CollectionViewSource绑定的ObservableCollection属性。) 当FilterText TextBox的值发生变化时,如何让CollectionViewSource重新进行自我刷新? 非常感谢
我有一个关于WPF Grid Control的非常简单的问题。 我想在网格中的每一行设置一个底部边框,但只能find如何将每个单元格周围的所有4个边框..我的代码是非常简单的 <Grid Height="174" HorizontalAlignment="Left" Margin="23,289,0,0" Name="grid2" VerticalAlignment="Top" Width="730"> <Grid.RowDefinitions> <RowDefinition Height="45" /> <RowDefinition Height="25" /> <RowDefinition Height="25" /> <RowDefinition Height="25" /> <RowDefinition Height="25" /> <RowDefinition Height="25" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="255" /> <ColumnDefinition Width="95" /> <ColumnDefinition Width="95" /> <ColumnDefinition Width="95" /> <ColumnDefinition Width="95" /> <ColumnDefinition Width="95" /> </Grid.ColumnDefinitions> </Grid> 对于我正在使用的另一个网格,需要使用所有四个边框 <Border Grid.Column="0" […]
这是一个平凡的问题,但在我看来,在WPF中没有内置的方法。 只有似乎是WindowState属性是一个枚举没有帮助,因为我不能告诉窗口是否处于Normal或Maximized状态之前被最小化。 当单击任务栏图标窗口正在恢复正常,假设其以前的状态,但我似乎无法find任何定义的方法,这样做。 所以我一直在想,如果我只是缺less的东西,或者如果我需要使用一些自定义的交互逻辑。 ( 我会张贴我当前的解决scheme作为答案 )
我看到了很多关于如何在DataGrid中选定行的样例,例如: 如何设置DataGrid中选定行的颜色 我可以只禁用选定的行样式吗? 我不想重写select行更改的每一件事情。 只是不想要任何可见的变化。 比创build模板更容易 要么.. 禁用select行,如果这更容易..但从浏览这个论坛,似乎hacky以及 禁用在WPF DataGrid中select
我在Canvas里面有一个Grid像这样定义: <Canvas x:Name="outerCanvas"> <Grid Grid.Row="1" Name="cGrid" ShowGridLines="True" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type Canvas}}}" Height="{Binding Path=ActualHeight, RelativeSource={RelativeSource AncestorType={x:Type Canvas}}}"> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Rectangle Name="rectangle1" Stroke="Black" Fill="AntiqueWhite" /> <Rectangle Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="1" Grid.RowSpan="1" Name="rectangle2" Stroke="Black" Fill="AliceBlue" /> <Rectangle Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="1" Grid.RowSpan="1" Name="rectangle3" Stroke="Black" Fill="Aqua" /> <Rectangle Grid.Row="1" Grid.Column="0" […]
我们刚刚进入WPF中的MVVM。 我们用视图中绑定的“强types”属性(int,double?等)实现了ViewModel。 types转换工作正常,大多数,所以input数据很简单。 但是我们遇到了validation问题。 例如,如果在绑定到数字属性的文本框中input非数字值,则转换将失败,该属性将永远不会设置,并且我们从来没有机会向用户提供正确的反馈。 更糟糕的是,该属性保留了当前的值,导致视图中显示的内容与ViewModel中的实际内容不匹配。 所有这些都可以用价值转换器来处理,我知道。 但是我看到了一些意见,认为转换不应成为观点的责任。 在视图中input的是string,转换,validation等应该是ViewModel的责任(所以这个说法是这样的)。 如果是这样的话,我们应该将ViewModel的大部分属性重写为string,并通过IErrorInfo接口提供错误信息。 它肯定会使更简单,更精简的XAML。 另一方面,从视图devise者的angular度来看,转换,validation等将更less声明性,明确和灵活。 在我们看来,这两种方法是根本不同的,所以在我们决定之前,我们希望对这个问题有所了解。 所以:ViewModels应该向视图公开一个简化的,基于文本的界面,并在内部处理转换? 或者应该ViewModel属性公开实际的数据types,把这些杂事留给视图来处理? 更新: 很难在这里挑选一个胜利者,但是我最终落在了一个或多或less像我自己一样的人身上。 具体来说,我们决定保持ViewModel属性的types。 主要原因是它在视图devise中的灵活性,以及XAML中显式声明转换/格式化的能力。 我注意到一个假设,你会不同意我们这个观点的devise是固定和准备好的。 因此,在视图中不需要做出关于转换,格式化等的决定。 但是我们的过程是一个敏捷的过程,我们并没有事先弄清UI的细节。 事实上,把UI的细节留下来留给创造力,而且在我看来,即使是经过精心devise的devise,在整个实施过程中也总是会变形的。 所有这一切的重点是,虽然商业规则执法当然属于ViewModel,但在我们看来,简单的转换和格式化是一个视图。 这可能听起来像异端,但我并不认为视图中的types转换需要unit testing(只要我们unit testing实际的types转换器)。 总而言之,一个伟大的讨论,伙计,制定完善,知情的意见。 谢谢。