简体   繁体   中英

How to create databinding in code behind using the same object that is initiated in xaml?

I have the following code :

    <Window x:Class="WpfApplication3.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:WpfApplication3" xmlns:oxy="http://oxyplot.org/wpf"
        xmlns:vm="clr-namespace:ViewModel;assembly=ViewModel"
        Background="#FFDEDEDE" 
        WindowStyle="None"
        AllowsTransparency="True"
       WindowStartupLocation="CenterScreen"

    mc:Ignorable="d"
        Title="Compression Test" Height="1080" Width="1920">


    <Window.Resources>
        <vm:MainViewModel x:Key="vmMain"
         sampleCount="100" />
    </Window.Resources>
    <Grid x:Name="gridUI">

        <StackPanel Orientation="Vertical">
            <StackPanel Height="100">

                <Border Background="#FF8986D3" Height="100" Margin="0,0,0,30" >

                    <TextBlock Text="COMPRESSION TEST"  FontFamily="Sans-serif" FontSize="30" Foreground="#FFF9F9F9" VerticalAlignment="Center" FontWeight="Medium" HorizontalAlignment="Center"/>

                </Border>

            </StackPanel>

            <StackPanel Orientation="Horizontal" Height="auto">
                <Border BorderBrush="White" BorderThickness="2" >
                <StackPanel Orientation="Vertical" Width="200" Height="1080">


                    <Label  FontSize="24" FontFamily="Sans-serif" FontWeight="Medium" Name="doc" Foreground="White" Background="#FFA39AD8" Width="200" HorizontalContentAlignment="Center" Height="43">Files</Label>
                    <Border BorderBrush="#FFD4D4D4" BorderThickness="0.5" Grid.Row="3"></Border>


                    <StackPanel Name="sp_doc" Margin="0,10,0,0" >
                        <StackPanel Orientation="Horizontal"  Name="sp_sample_button" Grid.Row="0" Grid.Column="0">
                            <Image Source="pack://application:,,,/Resources/413.png" Height="40" Width="40"  UseLayoutRounding="True"   MouseDown="sampleDropDown" Cursor="Hand" Margin="5,0,0,0" Name="up_arrow"/>
                            <Image Source="pack://application:,,,/Resources/412.png" Height="40" Width="40"  UseLayoutRounding="True"   MouseDown="sampleDropDown" Cursor="Hand" Margin="5,0,0,0" Name="down_arrow" Visibility="Collapsed"/>
                            <!--<Button x:Name="sss" Click="sampleDropDown">s</Button>-->
                            <Label FontSize="18" FontFamily="Sans-serif" FontWeight="Light" Name="sam" Foreground="White" Margin="10">Samples</Label>

                        </StackPanel>
                        <StackPanel Orientation="Vertical" Name="sp_s">

                        </StackPanel>
                        <StackPanel Orientation="Horizontal" Grid.Column="1" Grid.Row="1">
                            <Image Source="pack://application:,,,/Resources/413.png" Height="40" Width="40"  UseLayoutRounding="True"  RenderTransformOrigin="-0.,0.558" MouseDown="reportDropDown" Cursor="Hand" Margin="5,0,0,0" Name="up_arrow1"/>
                            <Image Source="pack://application:,,,/Resources/412.png" Height="40" Width="40"  UseLayoutRounding="True"  Cursor="Hand" Margin="5,0,0,0" Name="down_arrow1" Visibility="Collapsed" MouseDown="reportDropDown"/>
                            <!--<Button Click="reportDropDown">r</Button>-->
                            <Label FontFamily="Sans-serif" FontWeight="Light" Foreground="White" FontSize="18" Margin="10">Reports</Label>
                        </StackPanel>
                        <StackPanel Orientation="Vertical" Name="sp_r">

                        </StackPanel>

                    </StackPanel>




                </StackPanel>
                </Border>
                <StackPanel Width="1781">
                    <StackPanel Orientation="Horizontal" Background="#FFFDFDFD" Height="111">
                        <TextBox Name="sampleCount" Text="{Binding sampleCount, Source={StaticResource vmMain}, UpdateSourceTrigger=PropertyChanged}" Width="200"></TextBox>
                        <Button Cursor="Hand"  Height="75" Width="75" Style="{StaticResource CircleButton}"  FontFamily="Sans-Serif" FontSize="25" Foreground="White" Click="NewSample_Click" Content="+" Margin="20,0,0,0" Background="#FFACAABF" />

                        <StackPanel Margin="20,19,0,0">
                            <Image Source="pack://application:,,,/Resources/file512.png" Height="75" Width="75"  UseLayoutRounding="True" Margin="0,0,0,0"  MouseDown="CreateReport_Click" Cursor="Hand" SnapsToDevicePixels="True"/>
                        </StackPanel>

                        <Image Source="pack://application:,,,/Resources/play1.png" Height="75" Width="75"  UseLayoutRounding="True" Margin="20,18,0,18"  MouseDown="CreateReport_Click" Cursor="Hand" SnapsToDevicePixels="True"/>

                        <Image Source="pack://application:,,,/Resources/1131.png" Height="75" Width="75"  UseLayoutRounding="True" Margin="1340,0,0,0"  MouseDown="CreateReport_Click" Cursor="Hand"/>

                    </StackPanel>
                    <Frame x:Name="newSampleFrame" Content="" HorizontalAlignment="center" VerticalAlignment="center" Width="934" Height="456" NavigationUIVisibility="Hidden" RenderTransformOrigin="0.408,0.5" Visibility="Collapsed"/>
                    <Frame x:Name="reportFrame"  Content=""  HorizontalAlignment="Center" Height="842" VerticalAlignment="Center" Width="595" Margin="0,100,0,0" NavigationUIVisibility="Hidden"/>
                    <Frame x:Name="graphFrame"  Content="" HorizontalAlignment="Center" Height="456"  VerticalAlignment="Center" Width="934" NavigationUIVisibility="Hidden" Visibility="Collapsed"/>
                </StackPanel>


            </StackPanel>
        </StackPanel>

    </Grid>
</Window>

MainViewModel.cs :

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ViewModel
{

public class MainViewModel : ObservableObject
{

    public MainViewModel()
    {

    }
    private string[]  sampleName;
    private string _sampleCount;
    public Data obj2 = new Data();



    public string this[int pos]
    {
        get
        {
            return sampleName[pos];
        }

        set
        {
            sampleName[pos] = value;

        }

    }

   public string sampleCount
    {

        get
        {
            return _sampleCount;

        }
        set
        {
            if (value != _sampleCount)
            {

                _sampleCount = value;
                OnPropertyChanged("sampleCount");
                Console.WriteLine("Test");
                Console.WriteLine(value);
                obj2.sampleCount = value;
                SaveFile.saveFileMain(obj2);

            }
        }
    }

} 
}

And I have the following code that create a textblock whenever I click on the OK button :

window2.xaml.cs:

private void Ok_Click(object sender, MouseButtonEventArgs e)
    {
        MainWindow win = (MainWindow)Application.Current.MainWindow;
        int i = 1;  // counter for the name of each new textblock
        string name = String.Concat("sample", i);

        // add textblok to the document list of new samples

        if (File_name.Text != "")
        {
            TextBlock sampleText = new TextBlock();


            sampleText.Text = File_name.Text;
            sampleText.FontSize = 14;
            sampleText.FontFamily = new FontFamily("Sans-serif");
            sampleText.FontWeight = FontWeights.DemiBold;
            sampleText.Margin = new Thickness(20,0,0,0);
            sampleText.Name = name;
            sampleText.PreviewMouseDown += new MouseButtonEventHandler(test1);
            sampleText.Visibility = System.Windows.Visibility.Collapsed;

            //binding 

            Binding myBinding = new Binding();
            myBinding.Source =
            myBinding.Path = new PropertyPath("sampleName");
            myBinding.Mode = BindingMode.TwoWay;
            myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            sampleText.SetBinding(TextBlock.TextProperty, myBinding);


            Grid.SetColumn(sampleText, 0);

            win.sp_s.Children.Add(sampleText);

            // checking if the drop down of sample is already open, if so it will show the last textblock with pressing the arrow button.
            var textblockSample = win.sp_s.Children.OfType<TextBlock>().FirstOrDefault();
            if (textblockSample.Visibility == System.Windows.Visibility.Visible)
            {
                sampleText.Visibility = System.Windows.Visibility.Visible;
            }
        }
        i += 1;  // increasing the loop of names by 1
        this.Close();
    }

Is it possible to use the same object that is initiated in xaml (vmMain) as a source for binding the textblock (sample text) to sampleName property?

Not sure why you don't set DataContext of your MainWindow to MainViewModel .

<Window.DataContext>
    <StaticResourceExtension ResourceKey="vmMain" />
</Window.DataContext>

Or, you can even set DataContext via MainWindow 's code behind, which you don't seem to intent to not keep it untouched.

Then to set binding source:

myBinding.Source = this.DataContext;

In the case you refused to set the DataContext, you still can:

myBinding.Source = this.FindResource("vmMain") as MainViewModel;

Not sure if I managed to solve your problem.

Edit

I just realised your binding is in window2 . You should do this:

myBinding.Source = win.DataContext;

Similarly, myBinding.Source = this.FindResource("vmMain") as MainViewModel; should also be changed to myBinding.Source = win.FindResource("vmMain") as MainViewModel; .

This is provided you still have that MainWindow win = (MainWindow)Application.Current.MainWindow; line there.

I believe that what you are looking for is the resources property:

myBinding.Source = Resources["vmMain"];

Resource allows you to access the XAML-defined (or otherwise) resources for the current object - the window. You can also access the resources of any FrameworkElement in the same manner.


EDIT: I hadn't noted the fact that the vmMain was in a different class. With this in mind, no there is no way to reference that object directly from Window2 as there may be multiple MainWindow s so you'd have to pick which MainWindow instance the vmMain should be taken from. What you can do, however is create vmMain in your Application object (App.xaml). This would then share that object across all FrameworkElement s in your application. To access this you could use

myBinding.Source = Application.Currennt.Resources["vmMain"];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM