【问题标题】:WPF Binding of a Control inside a UserControl用户控件内控件的 WPF 绑定
【发布时间】:2014-01-14 22:39:35
【问题描述】:

我在 UserControl 中有一个 ComboBox。我在带有 DataGrid 的窗口中使用 UserControl:UserControl DataContext 是 DataGrid SelectedItem。 UserControl 内部的 ComboBox 通过 SelectedValue 属性绑定到 SelectedItem 的“ID”字段。为了实现这一点,我像这样在 UserControl 中编写了一个 DependencyProperty

Public Shared SelectedValueProperty As DependencyProperty = _
DependencyProperty.Register("SelectedValue", GetType(Object), GetType(ucEditCombo))
    Public Property SelectedValue() As Object
        Get
            Return CType(GetValue(SelectedValueProperty), Object)
        End Get
        Set(ByVal value As Object)
            SetCurrentValue(SelectedValueProperty, value)
        End Set
    End Property

并将 ComboBox SelectedValue 属性绑定到 XAML 中的 UserControl SelectedValue 属性:

<ComboBox SelectedValuePath="{Binding ElementName=EditCombo,Path=SelectedValuePath}"
          DisplayMemberPath="{Binding ElementName=EditCombo,Path=DisplayMemberPath}"
          ItemsSource="{Binding ElementName=EditCombo,Path=ItemsSource}"
          SelectedValue="{Binding ElementName=EditCombo,Path=SelectedValue,Mode=TwoWay}"
          Visibility="{Binding ElementName=EditCombo,Path=ComboVisibility}"
          Name="cmb"/>

(EditCombo 是我在 XAML 中给 UserControl 的 x:Name)。

运行应用程序我不是以下内容:

  1. 如果我更改 DataGrid 选择,则 ComboBox 显示的值会正确更改。
  2. 只要我直接在控件上更改 ComboBox 选定值,DataGrid 中的值就不会更新,并且 ComboBox 不再绑定到 DataGrid SelectedItem。

【问题讨论】:

    标签: wpf data-binding user-controls


    【解决方案1】:

    有关更新原始 DataGrid SelectedItem 的问题并不明显,尽管我认为这与 ComboBox 上的绑定有关。我需要查看 Window xaml 和 UserControl 的代码来确定。

    我尝试通过示例重现该问题,但我无法重现。因此,为了加快您的前进速度,我在下面发布了示例。

    假设:UserControl 正在尝试修改绑定到 SelectedValue DependencyProperty 的对象的属性,而不是尝试替换该对象。 如果假设不正确,使用与问题相关的额外代码更新问题,我将尝试更新我的答案。

    首先,我在为 StackOverflow 问题创建代码时使用了一个模型,称为 ItemModel。

    Public Class ItemModel
        Public Property Id as Guid
        Public Property Text as String
    End Class
    

    在 Window 上,我创建了一个名为 Items 的 ObservableCollection(Of ItemModel) 属性。它包含 3 个项目,每个项目的 Text 属性设置为值“一”、“二”或“三”之一。每个项目的 Id 都设置为新的 guid。

    所以,我的主窗口 xaml 看起来像

    <Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:this="clr-namespace:StackOverflow._20798974"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        Title="MainWindow" Height="350" Width="525">
        <DockPanel>
            <StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom">
                <this:ucEditCombo SelectedValue="{Binding ElementName=MyGrid, Path=SelectedItem}" />
            </StackPanel>
            <DataGrid x:Name="MyGrid" ItemsSource="{Binding Path=Items}" AutoGenerateColumns="False" >
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Id" Binding="{Binding Id}"/>
                    <DataGridTextColumn Header="Text" Binding="{Binding Text}" Width="*"/>
                </DataGrid.Columns>
            </DataGrid>
        </DockPanel>
    </Window>
    

    ucEditCombo UserControl 背后的代码包含您在上述问题中定义的 DependencyProperty 和一个 ObservableCollection(Of String),其中填充了值“一”、“二”、“三”和“四”。

    用户控件的xaml是

    <UserControl x:Class="ucEditCombo" 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"
                 xmlns:this="clr-namespace:StackOverflow._20798974"
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <Grid DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type this:ucEditCombo}}}">
            <ComboBox ItemsSource="{Binding Path=Items}" SelectedValue="{Binding Path=SelectedValue.Text}" />
        </Grid>
    </UserControl>
    

    上面的示例允许我选择一个 DataGrid 项目并让该项目的 Text 属性立即出现在 ComboBox 中。它还允许在 ComboBox 中选择不同的值,并在 DataGrid 中更新该值。

    注意事项。

    1. 在 Controls 构造函数中设置 Control 的 DataContext 将破坏 Window 上的 SelectedItem 绑定。为了解决这个问题,我在 UserControl 的第一个内容元素(一个 Grid 元素)上设置了 DataContext。
    2. DataContext 设置为 UserControl 本身,简化了 Combobox 上的一些绑定。
    3. 当我们修改 DependencyProperty 的属性时,我们会处理很多 WPF 绑定子系统通知。
    4. SelectedValue 和 SelectedItem 的默认绑定模式是 TwoWay。

    我希望这会有所帮助。

    【讨论】:

    • 谢谢你的回答,很有启发性!对于我的个人问题,我唯一需要改变的是:(1)我在 ucEditCombo XAML 中设置了 SelectedValue="{Binding Path=SelectedValue}"; (2) 使用 UserControl 的 Window XAML 中的 SelectedValue="{Binding ElementName=MyGrid,Path=SelectedItem[field_Name]}"。通过这样做,我可以绑定到当前选定的 DataRowView 中我需要的任何字段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-06
    • 1970-01-01
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    相关资源
    最近更新 更多