gpt4 book ai didi

c# - 数据绑定(bind)不适用于我的依赖属性

转载 作者:行者123 更新时间:2023-11-30 22:11:43 24 4
gpt4 key购买 nike

我正在使用 .NET Framework 4 和 MVVM Light Toolkit 开发 WPF 应用程序我创建了一个自定义用户控件,它只包含一个 DataGrid:

<UserControl
x:Class="PadacEtl.Matcher.Views.LaraDataGrid"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
DataContext="{Binding}">

<DataGrid ItemsSource="{Binding}" SelectionChanged="SelectionChanged">
<DataGrid.Columns>
<DataGridTextColumn Header="Value" Binding="{Binding Model.Value}" />
</DataGrid.Columns>
</DataGrid>
</UserControl>

这个控件定义了一个依赖属性SelectedItems:

public partial class CustomDataGrid : UserControl
{
public IEnumerable<ItemViewModel> SelectedItems
{
get { return (IEnumerable<ItemViewModel>)GetValue(SelectedItemsProperty); }
set { SetValue(SelectedItemsProperty, value); }
}

public static readonly DependencyProperty SelectedItemsProperty =
DependencyProperty.Register("SelectedItems", typeof(IEnumerable<ItemViewModel>),
typeof(CustomDataGrid), new PropertyMetadata(new List<ItemViewModel>()));

public CustomDataGrid()
{
InitializeComponent();
}

private void SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var dataGrid = sender as DataGrid;
SelectedItems = dataGrid.SelectedItems.Cast<ItemViewModel>();
}
}

最后,这个自定义用户控件在 View 中使用,定义如下:

<Window x:Class="Project.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:uc="clr-namespace:Project.Views"
Title="Project"
Height="700" Width="1050"
DataContext="{Binding Source={StaticResource Locator}, Path=Main}">

<Window.Resources>
<ResourceDictionary Source="Styles.xaml" />
</Window.Resources>

<Grid>
<uc:CustomDataGrid DataContext="{Binding Items}"
SelectedItems="{Binding SelectedItems}" />
</Grid>
</Window>

与相应的ViewModel:

public class MainViewModel : ViewModelBase
{
public ObservableCollection<ItemViewModel> Items { get; private set; }

private IEnumerable<ItemViewModel> selectedItems = new List<ItemViewModel>();
public IEnumerable<ItemViewModel> SelectedItems
{
get { return selectedItems; }
set
{
if (value != selectedItems)
{
selectedItems = value;
RaisePropertyChanged(() => SelectedItems);
}
}
}

public MainViewModel()
{
//Something useful to feed Items
}
}

我的问题是:当我从我的CustomDataGrid中选择一行或多行时,MainViewModel 中的SelectedItems 是没有更新。我想我没有很好地连接某些东西,但我找不到什么。

有什么想法吗?

最佳答案

您必须对您的 SelectedItems 属性进行双向绑定(bind)。您要么像这样在绑定(bind)表达式中明确地这样做:

<uc:CustomDataGrid ... SelectedItems="{Binding SelectedItems, Mode=TwoWay}"/>

或者您设置 FrameworkPropertyMetadataOptions.BindsTwoWayByDefault依赖属性声明中的标志:

public static readonly DependencyProperty SelectedItemsProperty =
DependencyProperty.Register(
"SelectedItems",
typeof(IEnumerable<ItemViewModel>),
typeof(CustomDataGrid),
new FrameworkPropertyMetadata(
null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

另请注意,将默认属性值设置为新集合实例是不好的做法,因为该集合将用作该属性所有“实例”的默认值。换句话说,CustomDataGrid 的两个实例上 SelectedItems 属性的默认值将是同一个集合对象。如果您向一个添加项目,则这些项目也将包含在另一个中。您必须在控件的构造函数中设置默认值。


编辑:在再次查看您的 UserControl 以及您如何绑定(bind)其属性后,我意识到它无法按照您设计的方式工作。按照绑定(bind)声明中的方式设置 DataContext

<uc:CustomDataGrid DataContext="{Binding Items}"
SelectedItems="{Binding SelectedItems}"/>

需要显式设置SelectedItems绑定(bind)的绑定(bind)源对象,可能像这样

SelectedItems="{Binding SelectedItems, Source={StaticResource myViewModelInstance}}"

除了 SelectedItems 属性之外,您的控件还应该具有可绑定(bind)的 ItemsItemsSource 而不是那样做。然后,您可以像这样简单地编写绑定(bind):

<uc:CustomDataGrid DataContext="{StaticResource myViewModelInstance}"
ItemsSource="{Binding Items}" SelectedItems="{Binding SelectedItems}"/>

关于c# - 数据绑定(bind)不适用于我的依赖属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20090261/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com