如何在xaml中绑定用户控件

本文关键字:绑定 用户 控件 xaml | 更新日期: 2023-09-27 18:22:49

我有一个包含数据网格和"过滤器面板"的MainWindow。过滤器面板可以通过用户输入(点击按钮)进行更改。我试图通过数据绑定来实现它。Im面临的问题是过滤器面板(它是一个用户控件)没有加载或刷新。

主窗口xaml:

 <Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="250*" />
        <ColumnDefinition Width="253*" />
    </Grid.ColumnDefinitions>
    <DataGrid AutoGenerateColumns="True" Height="200" HorizontalAlignment="Left" Margin="23,28,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="200" ItemsSource="{Binding OverviewableItems}" /> 
    <UserControl Grid.Column="1" Content="{Binding UserControl}" DataContext="{Binding}" Grid.ColumnSpan="2" />
    <Button Content="PersonFilter" Height="23" HorizontalAlignment="Left" Margin="23,268,0,0" Name="buttonPersonFilter" VerticalAlignment="Top" Width="75" Click="buttonPersonFilter_Click" />
    <Button Content="ProjectFilter" Height="23" HorizontalAlignment="Left" Margin="132,268,0,0" Name="buttonProjectFilter" VerticalAlignment="Top" Width="75" Click="buttonProjectFilter_Click" />
</Grid>

代码背后:

 private ViewModel _viewModel;
    public MainWindow()
    {
        _viewModel = new ViewModel(new DataProvider());
        DataContext = _viewModel;
        _viewModel.PropertyChanged += _viewModel.SetFilterType;
        InitializeComponent();
    }

    private void buttonProjectFilter_Click(object sender, RoutedEventArgs e)
    {
        _viewModel.OverviewType = OverviewType.Project;
    }
    private void buttonPersonFilter_Click(object sender, RoutedEventArgs e)
    {
        _viewModel.OverviewType = OverviewType.Person;
    }

第一个用户控制:

<Grid>
    <DatePicker Grid.Column="1" Grid.Row="1" Height="25" HorizontalAlignment="Left" Margin="19,18,0,0" Name="datePickerFundingTo" VerticalAlignment="Top" Width="115" Text="{Binding ElementName=ProjectFilter, Path=FundingTo}" />
</Grid>

这个用户控件的代码只有这个:

 public DateTime FundingTo { get; set; }
 public ProjectFilter()
    {
        FundingTo = DateTime.Now;
        InitializeComponent();
    }

其他用户控件:只包含一个TextBox和一个Button,为了简单起见,我没有添加任何代码

主窗口的ViewModel:

public class ViewModel  : INotifyPropertyChanged
{
    private UserControl _userControl;
    public UserControl UserControl
    {
        get { return _userControl; }
        set
        {
            if (_userControl == value)
            {
                return;
            }
            OnPropertyChanged("UserControl");
            _userControl = value;
        }
    }
    private OverviewType _overviewType = OverviewType.None;
    public OverviewType OverviewType
    {
        get { return _overviewType; }
        set
        {
            if (_overviewType == value)
            {
                return;
            }
            OnPropertyChanged("OverviewType");
            _overviewType = value;
        }
    }
    private ObservableCollection<IOverviewItem> _overviewableItems;
    public ObservableCollection<IOverviewItem> OverviewableItems
    {
        get { return _overviewableItems; }
        set
        {
            if (_overviewableItems == value)
            {
                return;
            }
            _overviewableItems = value;
        }
    }
    private readonly DataProvider _dataProvider;
    public event PropertyChangedEventHandler  PropertyChanged;
    public ViewModel(DataProvider dataProvider)
    {
        _dataProvider = dataProvider;
    }
    public void SetFilterType(object sender, EventArgs eventArgs)
    {
        switch (_overviewType)
        {
            case OverviewType.Project:
                _userControl = new ProjectFilter();
                break;
            case OverviewType.Person:
                _userControl = new PersonFilter();
                break;
        }
    }
    public void OnPropertyChanged(string name)
    {
        if (PropertyChanged == null)
            return;
        var eventArgs = new PropertyChangedEventArgs(name);
        PropertyChanged(this, eventArgs);
    }  
}

另外,我有一个枚举OverviewType,值为None、Project、Person。

属性更改事件已正确激发,但用户控件未刷新。有人能告诉我,我的解决方案中的缺陷在哪里?

我还有一个问题,如何从用户控件到主窗口视图模型进行通信?外汇:数据网格应该根据其过滤器进行更改。

如有任何帮助,我们将不胜感激。干杯

如何在xaml中绑定用户控件

这里有不同的问题。

  • 正如Clemens所说,您必须在更新值后解雇您的活动。但这不是这里的主要问题。

  • 第二个问题:您正在将您的新usercontrol影响到私人成员,因此您完全绕过了您的财产。

更换

_userControl = new ProjectFilter();

通过

this.UserControl = new ProjectFilter();
  • 第三个问题,与您的问题没有直接关系,但实际上是您的最大问题:您有架构设计问题须不知道有关视图的任何信息,因此不得引用视图中的控件。您可以从视图模型中激发一个事件,并在视图中添加一个事件处理程序,而不是编写绑定,因此更新用户控件的是视图

在更改属性的后备字段后,尝试激发PropertyChanged

public UserControl UserControl
{
     get { return _userControl; }
     set
     {
         if (_userControl != value) 
         {
            _userControl = value;              // first
             OnPropertyChanged("UserControl"); // second
         }
     } 
}

类似于OverviewType