【问题标题】:Update the TextBox.Text in Usercontrol from everywhere从任何地方更新 Usercontrol 中的 TextBox.Text
【发布时间】:2017-11-03 10:24:59
【问题描述】:

我面临一个似乎经常出现的问题,并且有很多解决方案,但我很抱歉,我不能/不能申请我的情况。让我总结一下拓扑:我有一个带有网格的主窗口 (MainWindow),在底部单元格中,我放置了一个由我编写的用户控件 (UC_StatusMonitor),带有一个用户控件 (LBL_CONN_Message) 内的文本框,我想在其中更新操作结果(例如“连接到设备 X”、“无法从 Y 读取数据”、“缺少字段”等)。这基本上用于通知用户某些事情是对还是错。我知道我必须使用 Dependancy 来解决这个问题,但我的实现不起作用(肯定我错过了一些东西)。

让我展示一下代码:

MainWindows.xaml

<Window x:Class="LUX.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:LUX"
        mc:Ignorable="d"
        Title="LUX" Name ="MainForm" Height="600" Width="800"  MinHeight="600" MinWidth="800">

    <Border Padding="10">

        <Grid Name="Main_Grid">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="160"/>
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="100"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="22"/>
            </Grid.RowDefinitions>

            <!-- others controls ....   -->


            <!-- Monitor   -->
            <StackPanel Name="Stack_Monitor" Grid.Row="2" Grid.Column="1">
                <Grid Name="BottomBar" Height="20">
                    <local:UC_StatusMonitor Height="100" Grid.Row="2" Grid.Column="1"/>
                </Grid>
            </StackPanel>
        </Grid>



    </Border>
</Window>

然后是控件的代码

UC_StatusMonitor.xaml

<UserControl x:Class="LUX.UC_StatusMonitor"
             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:local="clr-namespace:LUX"
             mc:Ignorable="d" 
             xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
             d:DesignHeight="20" d:DesignWidth="300">
    <Grid Name="UCR_Base" Background="White">
        <WrapPanel>
            ...
            <TextBox Name="LBL_CONN_Message" Margin = "10 0 0 0" VerticalAlignment="Center" IsReadOnly="True" BorderThickness="0" Text="{Binding MyTextProperty, ElementName=control}"/>
            ...
        </WrapPanel>
    </Grid>
</UserControl>

UC_StatusMonitor.xaml.cs

namespace LUX {
    /// <summary>
    /// Interaction logic for StatusMonitor.xaml
    /// </summary>
    public partial class UC_StatusMonitor : UserControl
    {
        Button[] MenuButtons;

        //// The dependency property which will be accessible on the UserControl
        public static readonly DependencyProperty MyTextPropertyProperty = DependencyProperty.Register("MyTextProperty", typeof(string), typeof(UC_StatusMonitor), new UIPropertyMetadata(String.Empty));

        public string MyTextProperty
        {
            get { return (string)GetValue(MyTextPropertyProperty); }
            set { SetValue(MyTextPropertyProperty, value); }

所以,我期望在任何地方(在所有进入工作区的类中,我都声明了一个状态监视器静态对象),我应该使用类似的指令

MyTextProperty = "已连接";

然后在文本框上看到这条消息进入用户控件。

显然,不会发生 :(

感谢和问候

【问题讨论】:

  • 我不建议您这样做,您最好有时间使用某种消息系统。如果您想采用这种方式,请尝试将 MyTextProperty 放在公共静态字符串等中。而不是 DependencyProperty。然后到 class.MyTextProperty = "Connected" 仅供参考:dotnetpattern.com/mvvm-light-messenger
  • 您看不到任何内容,因为您的DataContext UC 是从父级继承的。所以调用Text="{Binding MyTextProperty, ElementName=control}" 没有任何效果,因为xaml 中没有任何名称为control
  • 不确定是否完全理解:我在 UC_StatusMonitor 类中添加了以下行 'public static string MyTextProperty;'理论上我可以用 'UC_StatusMonitor.MyTextProperty = "Test";' 调用,对吗?
  • 我希望我的回答对您有所帮助,或者至少为您指明了正确的方向。如果您能回报我为帮助您所做的努力,我将不胜感激。问候 XAMlMAX

标签: c# wpf xaml user-controls


【解决方案1】:

我已经设法让 UserControl 与 Binding 一起使用。
以下是我的做法:
UserControlWithBinding.xaml:

<UserControl x:Class="SO_app.UserControlWithBinding"
         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:local="clr-namespace:SO_app"
         mc:Ignorable="d" 
         d:DesignHeight="20" d:DesignWidth="300">
<Grid Name="IAmGroot"> <!-- Name this grid as you want as this is what we will use for internal Binding -->
    <TextBlock Text="{Binding Status}"/><!-- Because this grid is bound to the control it self you will always use this property, unless you rename it :-) -->
</Grid>


现在UserControlWithBinding.xaml.cs后面的代码:

/// <summary>
/// Interaction logic for UserControlWithBinding.xaml
/// </summary>
public partial class UserControlWithBinding : UserControl
{
    public UserControlWithBinding()
    {
        InitializeComponent();
        IAmGroot.DataContext = this;// this is where we set the data context for the grid so it uses the UserControl and not the inherited one. This will allow us to have the DataContext for User Control to be still inherited but the grid will look into a UserControl as an object to assign it to it's data context.
    }

    public string Status
    {
        get { return (string)GetValue(StatusProperty); }
        set { SetValue(StatusProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Status.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty StatusProperty =
        DependencyProperty.Register("Status", typeof(string), typeof(UserControlWithBinding), new PropertyMetadata(null));//note that I am using null and not string.Empty


}  



现在让我们在 xaml 中使用我们的控件:
<local:UserControlWithBinding Status="{Binding PropertyThatYouWantToBindThisControlsText}"/>  

这应该可以解决您的问题。

【讨论】:

  • 非常感谢。澄清一下,您指的是“PropertyThatYouWantToBindThisControlsText”吗?
  • 您将在 VM 中使用它而不是 MyTextProperty = "Connected";,您将拥有一个属性为 string Status {get;set;}//with INPC,然后将填充文本。希望这是有道理的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多